{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1> Machine Learning Model training and serving </h1>\n",
    "\n",
    "The training architecture involves collecting data from the two sources, mashing them up with Dataflow and saving the results in BigQuery. That data is used for ML training in Cloud ML.  Then, the trained model is used to orchestrate windmills.\n",
    "\n",
    "<img src=\"training_arch.png\" />"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%projects set ml-autoawesome"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import os\n",
    "PROJECT = 'ml-autoawesome'    # CHANGE THIS\n",
    "BUCKET = 'ml-autoawesome-cmle'  # CHANGE THIS\n",
    "REGION = 'us-central1' # CHANGE THIS\n",
    "\n",
    "os.environ['PROJECT'] = PROJECT # for bash\n",
    "os.environ['BUCKET'] = BUCKET # for bash\n",
    "os.environ['REGION'] = REGION # for bash"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "project=ml-autoawesome\n",
      "bucket=ml-autoawesome-cmle\n",
      "region=us-central1\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Updated property [core/project].\n",
      "Updated property [compute/region].\n"
     ]
    }
   ],
   "source": [
    "%bash\n",
    "echo \"project=$PROJECT\"\n",
    "echo \"bucket=$BUCKET\"\n",
    "echo \"region=$REGION\"\n",
    "gcloud config set project $PROJECT\n",
    "gcloud config set compute/region $REGION\n",
    "#gcloud beta ml init-project -q"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2> Step 1:  Import Python packages that we need </h2>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "import google.datalab.ml as ml\n",
    "import apache_beam as beam\n",
    "from tensorflow.python.lib.io import file_io\n",
    "import json\n",
    "import shutil"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "INDIR = '.'\n",
    "OUTDIR = '.'\n",
    "os.environ['OUTDIR'] = OUTDIR"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2> 2. Preprocessing </h2>\n",
    "\n",
    "Align the radar and windmill data temporally and compute moving averages."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def make_preprocessing_fn():\n",
    "  # stop-gap ...\n",
    "  def _scalar_to_vector(scalar):\n",
    "    # FeatureColumns expect shape (batch_size, 1), not just (batch_size)\n",
    "    return api.map(lambda x: tf.expand_dims(x, -1), scalar)\n",
    "  \n",
    "  def preprocessing_fn(inputs):\n",
    "    result = {col: _scalar_to_vector(inputs[col]) for col in CSV_COLUMNS}\n",
    "    for name in SCALE_COLUMNS:\n",
    "      result[name] = _scalar_to_vector(mappers.scale_to_0_1(inputs[name]))\n",
    "    return result\n",
    "\n",
    "  return preprocessing_fn\n",
    "\n",
    "def make_input_schema(mode):\n",
    "  input_schema = {}\n",
    "  if mode != tf.contrib.learn.ModeKeys.INFER:\n",
    "      input_schema[LABEL_COLUMN] = tf.FixedLenFeature(shape=[], dtype=tf.float32, default_value=0.0)\n",
    "  for name in ['dayofweek', 'key']:\n",
    "      input_schema[name] = tf.FixedLenFeature(shape=[], dtype=tf.string, default_value='null')\n",
    "  for name in ['hourofday']:\n",
    "      input_schema[name] = tf.FixedLenFeature(shape=[], dtype=tf.int64, default_value=0)\n",
    "  for name in SCALE_COLUMNS:\n",
    "      input_schema[name] = tf.FixedLenFeature(shape=[], dtype=tf.float32, default_value=0.0)\n",
    "      \n",
    "  input_schema = dataset_schema.from_feature_spec(input_schema)\n",
    "  return input_schema\n",
    "\n",
    "def make_coder(schema, mode):\n",
    "  import copy\n",
    "  column_names = copy.deepcopy(CSV_COLUMNS)\n",
    "  if mode == tf.contrib.learn.ModeKeys.INFER:\n",
    "    column_names.pop(LABEL_COLUMN)\n",
    "  coder = coders.CsvCoder(column_names, schema)\n",
    "  return coder\n",
    "\n",
    "def preprocess_all(pipeline, training_data, eval_data, predict_data, output_dir, mode=tf.contrib.learn.ModeKeys.TRAIN):\n",
    "  path_constants = PathConstants()\n",
    "  work_dir = os.path.join(output_dir, path_constants.TEMP_DIR)\n",
    "  \n",
    "  # create schema\n",
    "  input_schema = make_input_schema(mode)\n",
    "\n",
    "  # coder\n",
    "  coder = make_coder(input_schema, mode)\n",
    "\n",
    "  # 3) Read from text using the coder.\n",
    "  train_data = (\n",
    "      pipeline\n",
    "      | 'ReadTrainingData' >> beam.io.ReadFromText(training_data)\n",
    "      | 'ParseTrainingCsv' >> beam.Map(coder.decode))\n",
    "\n",
    "  evaluate_data = (\n",
    "      pipeline\n",
    "      | 'ReadEvalData' >> beam.io.ReadFromText(eval_data)\n",
    "      | 'ParseEvalCsv' >> beam.Map(coder.decode))\n",
    "\n",
    "  # metadata\n",
    "  input_metadata = dataset_metadata.DatasetMetadata(schema=input_schema)\n",
    "\n",
    "  _ = (input_metadata\n",
    "       | 'WriteInputMetadata' >> io.WriteMetadata(\n",
    "           os.path.join(output_dir, path_constants.RAW_METADATA_DIR),\n",
    "           pipeline=pipeline))\n",
    "\n",
    "  preprocessing_fn = make_preprocessing_fn()\n",
    "  (train_dataset, train_metadata), transform_fn = (\n",
    "      (train_data, input_metadata)\n",
    "      | 'AnalyzeAndTransform' >> tft.AnalyzeAndTransformDataset(\n",
    "          preprocessing_fn, work_dir))\n",
    "\n",
    "  # WriteTransformFn writes transform_fn and metadata to fixed subdirectories\n",
    "  # of output_dir, which are given by path_constants.TRANSFORM_FN_DIR and\n",
    "  # path_constants.TRANSFORMED_METADATA_DIR.\n",
    "  transform_fn_is_written = (transform_fn | io.WriteTransformFn(output_dir))\n",
    "\n",
    "  (evaluate_dataset, evaluate_metadata) = (\n",
    "      ((evaluate_data, input_metadata), transform_fn)\n",
    "      | 'TransformEval' >> tft.TransformDataset())\n",
    "\n",
    "  train_coder = coders.ExampleProtoCoder(train_metadata.schema)\n",
    "  _ = (train_dataset\n",
    "       | 'SerializeTrainExamples' >> beam.Map(train_coder.encode)\n",
    "       | 'WriteTraining'\n",
    "       >> beam.io.WriteToTFRecord(\n",
    "           os.path.join(output_dir,\n",
    "                        path_constants.TRANSFORMED_TRAIN_DATA_FILE_PREFIX),\n",
    "           file_name_suffix='.tfrecord.gz'))\n",
    "\n",
    "  evaluate_coder = coders.ExampleProtoCoder(evaluate_metadata.schema)\n",
    "  _ = (evaluate_dataset\n",
    "       | 'SerializeEvalExamples' >> beam.Map(evaluate_coder.encode)\n",
    "       | 'WriteEval'\n",
    "       >> beam.io.WriteToTFRecord(\n",
    "           os.path.join(output_dir,\n",
    "                        path_constants.TRANSFORMED_EVAL_DATA_FILE_PREFIX),\n",
    "           file_name_suffix='.tfrecord.gz'))\n",
    "\n",
    "  if predict_data:\n",
    "    predict_mode = tf.contrib.learn.ModeKeys.INFER\n",
    "    predict_schema = make_input_schema(mode=predict_mode)\n",
    "    tsv_coder = make_coder(predict_schema, mode=predict_mode)\n",
    "    predict_coder = coders.ExampleProtoCoder(predict_schema)\n",
    "    _ = (pipeline\n",
    "         | 'ReadPredictData' >> beam.io.ReadFromText(predict_data,\n",
    "                                                     coder=tsv_coder)\n",
    "         # TODO(b/35194257) Obviate the need for this explicit serialization.\n",
    "         | 'EncodePredictData' >> beam.Map(predict_coder.encode)\n",
    "         | 'WritePredictData' >> beam.io.WriteToTFRecord(\n",
    "             os.path.join(output_dir,\n",
    "                          path_constants.TRANSFORMED_PREDICT_DATA_FILE_PREFIX),\n",
    "             file_name_suffix='.tfrecord.gz'))\n",
    "\n",
    "  # Workaround b/35366670, to ensure that training and eval don't start before\n",
    "  # the transform_fn is written.\n",
    "  train_dataset |= beam.Map(\n",
    "      lambda x, y: x, y=beam.pvalue.AsSingleton(transform_fn_is_written))\n",
    "  evaluate_dataset |= beam.Map(\n",
    "      lambda x, y: x, y=beam.pvalue.AsSingleton(transform_fn_is_written))\n",
    "\n",
    "  return transform_fn, train_dataset, evaluate_dataset\n",
    "\n",
    "p = beam.Pipeline()\n",
    "output_dataset = 'windmills_control'\n",
    "transform_fn, train_dataset, eval_dataset = preprocess_all(\n",
    "      p, train_data_paths, eval_data_paths, predict_data_paths, output_dataset)\n",
    "\n",
    "p.run()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import datalab.bigquery as bq\n",
    "\n",
    "# get data from BigQuery\n",
    "query=\"\"\"\n",
    "SELECT\n",
    "  speed, weight, angular_momentum, wind_dir, moisture_content, radar_reflectivity, radar_cap,\n",
    "  radar_distance_to_nearest_cloud, radar_x, radar_y\n",
    "FROM\n",
    "  windmill_control\n",
    "\"\"\"\n",
    "df = bq.Query(query).to_dataframe()\n",
    "\n",
    "# Add a unique key (needed for batch prediction)\n",
    "df['key'] = 1000 + df.index.values\n",
    "\n",
    "# Use Pandas to create 90% training & 10% evaluation\n",
    "df = df.reindex(np.random.permutation(df.index))\n",
    "trainsize = (len(df)*9)/10\n",
    "df_train = df.head(trainsize)\n",
    "df_eval = df.tail(len(df) - trainsize)\n",
    "df_train.to_csv('cleanedup-train.csv', header=False, index_label=False, index=False)\n",
    "df_eval.to_csv('cleanedup-eval.csv', header=False, index_label=False, index=False)\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%bash\n",
    "ls -lrt cleanedup*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2> Local preprocessing, training and prediction </h2>\n",
    "\n",
    "Before we setup a large-scale ML pipeline, it is best practice to try out the code on a small dataset. This can be done on the machine on which you are running the Datalab notebook.\n",
    "\n",
    "Our pipeline consists of the following steps:\n",
    "<ol>\n",
    "<li> Preprocessing: this goes through the full dataset and computes min/max/mean of the input columns and target. These are useful as (a) defaults in case some input is missing in production  (b) to scale the inputs, because some ML optimizers work better on scaled inputs.\n",
    "<li> Training: this consists of adjusting weights on the model to reduce the error on the training dataset.\n",
    "<li> Evaluation: how well does this model do on the validation dataset? In the packaged solution, we can pass in the validation dataset and the evaluation will be carried out periodically during training itself. We don't need to do this separately.\n",
    "<li> Prediction: try out the trained model on some inputs to get an idea of what the model does in some hypothetical situation.\n",
    "</ol>\n",
    "<p/>\n",
    "<h3> Preprocessing </h3>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "!rm -rf ml_preproc ml_trained"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Starting local preprocessing.\n",
      "Local preprocessing done.\n"
     ]
    }
   ],
   "source": [
    "train_bq = ml.BigQueryDataSet(\n",
    "  table_pattern=('cleanedup-train*'),\n",
    "  schema_file=os.path.join('ml.json'))\n",
    "sd.local_preprocess(\n",
    "  dataset=train_bq,\n",
    "  output_dir=os.path.join(OUTDIR, 'ml_preproc'),\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "file_io.write_string_to_file(os.path.join(OUTDIR, 'ml_preproc/transforms.json'),\n",
    "                             json.dumps(transforms, indent=2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!cat $OUTDIR/ml_preproc/num*json"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3> Training </h3>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Starting local training.\n",
      "INFO:tensorflow:Using config: {'_save_checkpoints_secs': 600, '_num_ps_replicas': 0, '_keep_checkpoint_max': 5, '_tf_random_seed': None, '_task_type': None, '_environment': 'local', '_is_chief': True, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f54d765b5d0>, '_tf_config': gpu_options {\n",
      "  per_process_gpu_memory_fraction: 1\n",
      "}\n",
      ", '_task_id': 0, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_evaluation_master': '', '_keep_checkpoint_every_n_hours': 10000, '_master': ''}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Using config: {'_save_checkpoints_secs': 600, '_num_ps_replicas': 0, '_keep_checkpoint_max': 5, '_tf_random_seed': None, '_task_type': None, '_environment': 'local', '_is_chief': True, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f54d765b5d0>, '_tf_config': gpu_options {\n",
      "  per_process_gpu_memory_fraction: 1\n",
      "}\n",
      ", '_task_id': 0, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_evaluation_master': '', '_keep_checkpoint_every_n_hours': 10000, '_master': ''}\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/monitors.py:322: __init__ (from tensorflow.contrib.learn.python.learn.monitors) is deprecated and will be removed after 2016-12-05.\n",
      "Instructions for updating:\n",
      "Monitors are deprecated. Please use tf.train.SessionRunHook.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/monitors.py:322: __init__ (from tensorflow.contrib.learn.python.learn.monitors) is deprecated and will be removed after 2016-12-05.\n",
      "Instructions for updating:\n",
      "Monitors are deprecated. Please use tf.train.SessionRunHook.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/estimators/head.py:1362: scalar_summary (from tensorflow.python.ops.logging_ops) is deprecated and will be removed after 2016-11-30.\n",
      "Instructions for updating:\n",
      "Please switch to tf.summary.scalar. Note that tf.summary.scalar uses the node name instead of the tag. This means that TensorFlow will automatically de-duplicate summary names based on the scope they are created in. Also, passing a tensor or list of tags to a scalar summary op is no longer supported.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/estimators/head.py:1362: scalar_summary (from tensorflow.python.ops.logging_ops) is deprecated and will be removed after 2016-11-30.\n",
      "Instructions for updating:\n",
      "Please switch to tf.summary.scalar. Note that tf.summary.scalar uses the node name instead of the tag. This means that TensorFlow will automatically de-duplicate summary names based on the scope they are created in. Also, passing a tensor or list of tags to a scalar summary op is no longer supported.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Create CheckpointSaverHook.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Create CheckpointSaverHook.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Saving checkpoints for 1 into ./ml_trained/train/model.ckpt.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Saving checkpoints for 1 into ./ml_trained/train/model.ckpt.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 36.3639, step = 1\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 36.3639, step = 1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/estimators/head.py:1362: scalar_summary (from tensorflow.python.ops.logging_ops) is deprecated and will be removed after 2016-11-30.\n",
      "Instructions for updating:\n",
      "Please switch to tf.summary.scalar. Note that tf.summary.scalar uses the node name instead of the tag. This means that TensorFlow will automatically de-duplicate summary names based on the scope they are created in. Also, passing a tensor or list of tags to a scalar summary op is no longer supported.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/estimators/head.py:1362: scalar_summary (from tensorflow.python.ops.logging_ops) is deprecated and will be removed after 2016-11-30.\n",
      "Instructions for updating:\n",
      "Please switch to tf.summary.scalar. Note that tf.summary.scalar uses the node name instead of the tag. This means that TensorFlow will automatically de-duplicate summary names based on the scope they are created in. Also, passing a tensor or list of tags to a scalar summary op is no longer supported.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Starting evaluation at 2017-03-06-01:31:12\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Starting evaluation at 2017-03-06-01:31:12\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [1/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [1/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [2/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [2/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [3/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [3/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [4/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [4/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [5/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [5/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [6/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [6/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [7/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [7/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [8/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [8/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [9/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [9/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [10/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [10/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Finished evaluation at 2017-03-06-01:31:12\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Finished evaluation at 2017-03-06-01:31:12\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 1.03218\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 1.03218\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Skipping summary for global_step, must be a float or np.float32.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Skipping summary for global_step, must be a float or np.float32.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Validation (step 100): loss = 1.03218, global_step = 1\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Validation (step 100): loss = 1.03218, global_step = 1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 132.463\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 132.463\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0442949, step = 101\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0442949, step = 101\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 407.731\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 407.731\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0346903, step = 201\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0346903, step = 201\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 404.377\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 404.377\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0372787, step = 301\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0372787, step = 301\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 429.329\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 429.329\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0373653, step = 401\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0373653, step = 401\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 437.633\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 437.633\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0371831, step = 501\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0371831, step = 501\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 426.667\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 426.667\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.037286, step = 601\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.037286, step = 601\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 448.515\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 448.515\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0364593, step = 701\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0364593, step = 701\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 417.277\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 417.277\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0337301, step = 801\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0337301, step = 801\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 426.955\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 426.955\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0342755, step = 901\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0342755, step = 901\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 436.788\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 436.788\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0275392, step = 1001\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0275392, step = 1001\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 426.221\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 426.221\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0242356, step = 1101\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0242356, step = 1101\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 422.404\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 422.404\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0278054, step = 1201\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0278054, step = 1201\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 433.114\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 433.114\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0315829, step = 1301\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0315829, step = 1301\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 433.917\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 433.917\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0283409, step = 1401\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0283409, step = 1401\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 428.879\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 428.879\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0271956, step = 1501\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0271956, step = 1501\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 442.872\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 442.872\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0265643, step = 1601\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0265643, step = 1601\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 458.285\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 458.285\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0247513, step = 1701\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0247513, step = 1701\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 451.28\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 451.28\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0279163, step = 1801\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0279163, step = 1801\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 430.91\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 430.91\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.027566, step = 1901\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.027566, step = 1901\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 397.056\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 397.056\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.023281, step = 2001\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.023281, step = 2001\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 436.784\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 436.784\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0316509, step = 2101\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0316509, step = 2101\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 428.747\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 428.747\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0230275, step = 2201\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0230275, step = 2201\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 424.479\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 424.479\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0258873, step = 2301\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0258873, step = 2301\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 430.777\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:global_step/sec: 430.777\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0473793, step = 2401\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:loss = 0.0473793, step = 2401\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Saving checkpoints for 2500 into ./ml_trained/train/model.ckpt.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Saving checkpoints for 2500 into ./ml_trained/train/model.ckpt.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Loss for final step: 0.0288062.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Loss for final step: 0.0288062.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/estimators/head.py:1362: scalar_summary (from tensorflow.python.ops.logging_ops) is deprecated and will be removed after 2016-11-30.\n",
      "Instructions for updating:\n",
      "Please switch to tf.summary.scalar. Note that tf.summary.scalar uses the node name instead of the tag. This means that TensorFlow will automatically de-duplicate summary names based on the scope they are created in. Also, passing a tensor or list of tags to a scalar summary op is no longer supported.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/estimators/head.py:1362: scalar_summary (from tensorflow.python.ops.logging_ops) is deprecated and will be removed after 2016-11-30.\n",
      "Instructions for updating:\n",
      "Please switch to tf.summary.scalar. Note that tf.summary.scalar uses the node name instead of the tag. This means that TensorFlow will automatically de-duplicate summary names based on the scope they are created in. Also, passing a tensor or list of tags to a scalar summary op is no longer supported.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Starting evaluation at 2017-03-06-01:31:19\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Starting evaluation at 2017-03-06-01:31:19\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [1/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [1/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [2/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [2/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [3/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [3/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [4/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [4/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [5/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [5/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [6/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [6/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [7/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [7/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [8/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [8/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [9/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [9/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [10/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Evaluation [10/100]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Finished evaluation at 2017-03-06-01:31:19\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Finished evaluation at 2017-03-06-01:31:19\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Saving dict for global step 2500: global_step = 2500, loss = 0.0268624\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Saving dict for global step 2500: global_step = 2500, loss = 0.0268624\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Skipping summary for global_step, must be a float or np.float32.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Skipping summary for global_step, must be a float or np.float32.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Assets added to graph.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Assets added to graph.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:No assets to write.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:No assets to write.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:SavedModel written to: ./ml_trained/train/export/intermediate_evaluation_models/1488763880105/saved_model.pb\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:SavedModel written to: ./ml_trained/train/export/intermediate_evaluation_models/1488763880105/saved_model.pb\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Assets added to graph.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Assets added to graph.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:No assets to write.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:No assets to write.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:SavedModel written to: ./ml_trained/train/export/intermediate_prediction_models/1488763880831/saved_model.pb\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:SavedModel written to: ./ml_trained/train/export/intermediate_prediction_models/1488763880831/saved_model.pb\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Local training done.\n"
     ]
    }
   ],
   "source": [
    "eval_bq = ml.BigQueryDataSet(\n",
    "  file_pattern=('cleanedup-eval*'),\n",
    "  schema_file=os.path.join(OUTDIR, 'ml.json'))\n",
    "\n",
    "shutil.rmtree(os.path.join(OUTDIR, 'ml_trained'), ignore_errors=True)\n",
    "sd.local_train(\n",
    "  train_dataset=train_bq,\n",
    "  eval_dataset=eval_bq,\n",
    "  preprocess_output_dir=os.path.join(OUTDIR, 'ml_preproc'),\n",
    "  transforms=os.path.join(OUTDIR, 'ml_preproc/transforms.json'),\n",
    "  output_dir=os.path.join(OUTDIR, 'ml_trained'),\n",
    "  model_type='dnn_regression',\n",
    "  max_steps=2500,\n",
    "  layer_sizes=[1024]*4\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "evaluation_model\n",
      "model\n",
      "train\n"
     ]
    }
   ],
   "source": [
    "%bash\n",
    "ls $OUTDIR/ml_trained"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3> Prediction </h3>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>key</th>\n",
       "      <th>true_cost</th>\n",
       "      <th>predicted_cost</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>8557</td>\n",
       "      <td>11392.776966</td>\n",
       "      <td>10072.431564</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1896</td>\n",
       "      <td>7063.803673</td>\n",
       "      <td>9690.517783</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>5575</td>\n",
       "      <td>10495.557785</td>\n",
       "      <td>8345.039487</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3191</td>\n",
       "      <td>4917.296171</td>\n",
       "      <td>4244.951606</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2891</td>\n",
       "      <td>5928.281546</td>\n",
       "      <td>7767.778635</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    key     true_cost  predicted_cost\n",
       "0  8557  11392.776966    10072.431564\n",
       "1  1896   7063.803673     9690.517783\n",
       "2  5575  10495.557785     8345.039487\n",
       "3  3191   4917.296171     4244.951606\n",
       "4  2891   5928.281546     7767.778635"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_csv('{}/batch_predict/predictions-00000-of-00001.csv'.format(OUTDIR), names=('key','true_cost','predicted_cost'))\n",
    "df['true_cost'] = df['true_cost'] * 20000\n",
    "df['predicted_cost'] = df['predicted_cost'] * 20000\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeQAAAHTCAYAAAD20WvsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAMTQAADE0B0s6tTgAAIABJREFUeJzs3Xm8JGV5N/xfbb2vZz9n5sy+MgzrIKCoBJUlbkA0MeQN\nvO+ToEbFoEYFMUgQxd284vI8ZFOJmvjoQwyuQVDAsA4oDrMwDLOeM2fv03t3rffzR506092nl6rq\n6pmemev7+fhx6OU6VV3ddd33VcvFMcYYCCGEEHJC8Sd6AQghhBBCCZkQQgjpCpSQCSGEkC5ACZkQ\nQgjpApSQCSGEkC5ACZkQQgjpApSQCSGEkC4gnugF6EYzM7kTvQhVenrCSKUKJ3oxjovTaV0BWt9T\n2em0rsDS9e3vj57ApTk50Qy5y3EcIAg8OO5EL0nnnU7rCtD6nspOp3UFTr/17RRKyIQQQkgXoJI1\nIR1kGAay2Uzd58xZhYZ0OgenN7CNxeLgeRpPE3IqoYRMSAdlsxn815MvIRSOLHmOAxAOz6NQKMNJ\nPi4W8rj8ovVIJJKeLSch5MSjhExIh4XCEUSi8SWPcwAikQA43u8oIRNCTk2UkAkhTUvr7aDSOiH2\nUUIm5CRjGAYyGW+TZyaTwZM7pxCOenepCpXWCXGGEjIhJ5lSMY9HnptDT1+/ZzFnpycQiSbqltYJ\nIccHJWRCTkKNjku7VchnPYtFCHGHDu4QQgghXYASMiGEENIFKCETQgghXYCOIRNCThp0eRY5lVFC\nJoR0RO3lWe3cKtRCl2eRUxklZEJIR9RenuX2VqGV6PIsciqjhEwI6ZjKy7O8uFUoXZ5FTmV00IQQ\nQgjpAjRDJmRBJ04YymQyYAa1jiCEtEYJmZAFzVolumUd8/TuFCRCyKmKEjIhFeiWlISQE4USMjkp\nUXmZEHKqoYRMTkpUXiaEnGooIZOTFpWXCSGnErrsiRBCCOkClJAJIYSQLkAJmRBCCOkClJAJIYSQ\nLkAJmRBCCOkCdJY1IeS0Vtsm0gtWq0nD4MFxNO8h9lBCJoSc1mrbRHqBA8DhMF511grE49RnmdhD\nCZkQctrz+pp2DgAzZM/ikdMDJWTScXZvc2mV+dLpHFiLO1jSbS4JIacaSsik4+ze5pIDEA7Po1Ao\nt2xgT7e5JIScaighk+PCTkmQAxCJBMDx/pYJmW5zSQg51VBCJoSQDrDO3m51+MWpWCwOnqczt09F\nlJAJIaQDioU8fv1cBj293p29XSzkcflF65FI0JnbpyJKyKQK9RkmxDten71NTm2UkEkV6jNMCCEn\nBiVksgT1GSaEkOOPzgwghBBCugAlZEIIIaQLUMn6OHF7slSru1fRJRCEnD460QgDoP1It6CEfJy4\nPVmq2d2r6BIIQk4vnWiEQfuR7kEJ+Thyc7JUs7tXdWK0TJcoEdLd6FKqUxcl5JNYJ0bLdIkSIYSc\nGJSQT3J0iRIhhJwaKCHX8evHt6Mgc57GZGoWCA56GpMQQtrlxaGveief9vdTnc0pSsh18IIP4WSv\npzGLcyUYnkYkhJD2eXHoq/bk02Ihj/XrV3i2jKcLSsiEEHKaa/fQl5PWqaQxuvCMEEII6QKUkAkh\nhJAuQAmZEEII6QKUkAkhhJAuQAmZEEII6QKUkAkhhJAuQAmZEEII6QKUkAkhhJAuQDcGqUPXdSjl\nkscxDZQKecfv4wAwQ67bfrFULIDnReRz3nV8OpExm61rNy2nVzGdrO+JXE6vYrpd3+O9nF7gYN4B\nqyTryAe6e1m9iFm7bYsu9nUE4Bir1/aeEEIIIccTlawJIYSQLkAJmRBCCOkClJAJIYSQLkAJmRBC\nCOkClJAJIYSQLkAJmRBCCOkClJAJIYSQLkAJmRBCCOkClJAJIYSQLkAJmRBCCOkClJAJIYSQLkDN\nJbqQYTDwPOdpTF03IAjejr86EZMxBo47Pddd03SIouBpTF3XIQjdH9MwDPC8t59nJ2Kqmo6SrHsa\nE/D+e88Yw9h0HobHnQo2jsbh83mfNr5230MIhSOL/10s5HH5ReuRSCQ9/1snWn9/tOFzlJBJV/E6\nGRNCul8oHEEkGj/Ri3HCUcmaEEII6QKUkAkhhJAuQAmZEEII6QKUkAkhhJAuQAnZJcYYdN2Arhtg\nzLtTGa14XscE4GlMwzAW/t/L5dSrYnsZ0/oMvIlpdCQmx3GLy+sF83P0OiYDwHm6jTRNR6GsoVBS\nPPuOyoqGQ5M5HJ7MQvdoWXVdh6zoMAzvfvOGwTCbLmJmvgRF1TyLOT6TR7GsevYdNRjD9FwBjz1/\nFDPzRU9ikqXoLGsXzB0ct3jZi/mlN9q6FKReTI5jbV22YcbAYkzDMGAYrK3LdawfeGVMXW8vprmD\nQ8W6ctB1AzzPuT7r2jDMQQ3P8+A4bnEA1U5MxtjiJWlexQRQFcOKyXGc60vfrOXkOA6CUBkTHnyf\nar/3cL3tGWMollVourmsOgNyRQU+UUDA727XxBjDxGwB6bwMKxcVD6fRGw+gLxF0tZ0YYyjJGjTN\nADgOPM+b31mDgW9j3bMFBfmiAm1hOeVUCeGghGTU73o5U9ky5jJlyKoZVNM1SCIPnyS4/o5m8zLm\nMiUUyuaA4ZHnxrB8MILzNw1BEmlO5yVKyA5UJo7KL7cg8K53pLWJozIm4O5619rEYbF2xtZ6OIlr\nLyZzNCipTRzHYnKwkrKbgU7tQATA4t8wYzofQHQipnWdbL2Ybgc6tQO76pjuBhC6rlclYkvl995p\nzLKsQdHMZa1+HwdZ1aHqBoI+wdF12fPZMmbSpcVkZFF1hslUCZmCgqHeMCJByXZMRdVQVowl1wnz\nPL/w/TV/807XPZ2TIWvVy2kwIFdUUZY1xMM+hEM+2zFLZRWTqSLypepZtsEAWTW/S5LIQ5Lsf56K\nqmE6VUS2oFRdz6zqDAeO5jA7X8aGFQmsX5GkyxU9QgnZhkaJo5KbnV69nXytysRsN2bl++qxdiad\nimlnUFIvcdRyOtBplDhqY5qvtTe7c7qN7MZs9TqnA51GA7vqmM4GOnZiOh2U6LqBYlmD0eRGGGal\nACiWNQiCgVBAbPodlRUNR2cLS5JRrZKs49BEFtGQhGUDUQhNvk+6bt4ARF/43df7+9bjdhOzYZgz\n2GJZQ7OCt6ozzGZlFMoaklEfJKnxbtowGCbnqisC9WgGg6bo0A0Dkig03U6MMczMF5HOyVC0xkFz\nJRXPvjiDI9N5nLOhH73xYJO1InZQQm7BTuKoZGenZydx1BIEvulOz2n5sHJH2qg07jamYRjQNAax\nTjnLzk6+fszGAwinMa11ajYoaVQRON4xWw2eqgeL9raTnYGOnYFIbczK99V+nxhjKJU1aAtTrWbr\nf+TwYdzxiduQTqcRjUbxiTvuwsaN6xCouUMUYwyPP/07fOkLn0N6PgVwHK67/p14xStfi189+BP8\n5EffX0yYqdkZnLH1HPzNbZ9GpqCieHgevYkA+uLVZWzGGMqyBnWhPG33O8px3OLgqd665woKckUV\n3/6Xb+Cpxx+BJPkgiiLecf07cc55F9aN+7WvfAHbn/oNZqYn8a/f+9/YsGFj1fPzmTJmMksrArW+\n/sVPYN+LO5FJz+Gr3/wxwuEwJJEH01X83cfeD1VVAADJnj782f/4azAphkJZw9jBF/HAv30dmqog\nlujDtdd/ANF4z5L40/Ml/PrZMawciuGcDf11f/fEHo55eabPKeTYTr79Y47WTs/NDrmeyp2elzGB\nYzvryuV2q7I07lXMY4MSc6CjaQZ4vv1jo5Ux3ZT068WsTEztHm+tt1xOB4v1bnlZ+z23BotuPk8r\nfm3MsqJBaZE0Kv3Vu/4Sb37zW/GHb3ozHn7oQXzrm/+Mb377u+B5brGMncmXcWRiHu/5y+vw/g9/\nAhs3bwVjDPl8DtFobEnMD/7V/4N3/PmNeMUrX1v1eMgvYLgvjFBAgqIunLTVxm0srRMyrSRdVhbK\n0wvr/7tnn8SWs86DJPlw8MA+3P6R9+Af/vUB+P3+JbF273weg0Mj+PiH/wq33fFZnHPWGQgFfCjJ\nKibnlpanG9m94zksX7kGN//ltfjqNx9AMBQGAAg8YGgKotEIFFXH9//tX7Fn5+/wjhtvAwB85c53\n4S3X3YRV687E4w/dj7FDe/HH/+OjTf9WNCRh48ok1i1POPoM/+X/PFV1p658LoNLtg7TrTMJoKo6\nBIFva+cJ1M7unM+KGxEEfjGmkx1yq5iMMWiad8tZObuz/ka7qmd38GQ0XhnT+m8vYgLHErGdAdOm\nTZvw7ne/G4888ghKpRLe+9734s1vfjMAYMeOHfjCF76AQqEAXddx443vxFVXXQnDMPAXf/EXyGQy\nkGUZGzduxF133YVAIICnn34ad955J84++2zs2rUL7373u5HNZvHNb34TPp8Puq7jrrvuwllnnYXn\nn/897r770ygWiwgEArjllltw3nnnYXx8HFdffTWuv/56/OpXv0KhUMDHPvYxvPa1r11c5ve+9714\n5JFHcOGFF+LDH/5wVZWoJKuLZV875udT2LN7F772jXsBAJe97g343Gc/jfHxMSxfPopiWcN8roBs\nUcVDD/4CGzafiY2btwIwf2/1kvHePTuRzaZx/oWXLD72N++7Abfd+SWgpxcHjmYxmAxCkgRMTkzg\nz/70bXjr1X+Ep558HAYz8MEPfRSvuPAiW8tfWcbOFBRkcnJVefqc84/FWblqLcAYspl59A8MLYm1\necvZ5j8Yg6ozzKRlAGUUShr2vbQbP/jXe1EuFWEYBt54zXXYdvGldZdp89bzFv5VPffSDQC8D7Pp\nAubSZaQzOQDmdho//BJ4QcSqdWcCAM6/5Eo8/JPvQNNUiGLjY/C5oortu6cxNp3HH5w/2uSTIvVQ\nQq7DMAxHJz+0wvMcdL29WVyjmF42OLB2Jl7HdHPCk52YXn6e5qzQ+3tpW8neftlbwP33348jR47g\nbW97G84//3xEo1Hcfvvt+Id/+Af09fVhfn4e11xzDbZtOx8DAwP40pe+hHjcnF3ccccduO+++3Dj\njTcCAPbv34877rgDn/rUpwAA27Ztw89//nP09fVB13UoigJVVXHzzX+NO+/8JF796kvw7LPP4v3v\nfz8efPBBAEAul8PmzZtx00034bHHHsOnPvWpxYQMAKIo4gc/+EHddf/iFz6HZ5/dXnddb73tdmzZ\ncmbVY1OTk+jr66vatkNDw5ianMTy5aMAx6GsmJdxjR0+AFGUcPcdH8bc7DRWrVmP6//ifYjFE1Ux\nf/Xgj/Gay66sqg584avfWvy3wcz/Wdson89jzdq1+OsPfAgv7Pg9PvSBm/AfD/wMwWCoKu7Pf/YT\n3Pftb9bdtldf80e49PK3ND1W/PB//RiDw8vqJuNGFEVHLpfDt/7XF/GBj30W8UQP8rkM/u4j78S6\nTVuRSPbajmX50l0fwfiRAwhH4/jz9/wdACCTmkEi2b/4Gr8/CH8ghFwmhWTvYMuYmZzseDkIJWRC\nusrb3/52AMDo6CguuOACPPPMM0gkEjhy5AhuvPHGxetfOY7DgQMH0N/fj3/+53/Go48+Ck3TUCgU\ncO655y7GGx0dxbZt2xb/++KLL8ZHPvIRXHrppXjNa16DVatWYe/eveB5Hq985SsBAOeffz76+vqw\ne/duDA4OIhAI4PWvfz0A4Nxzz8XY2FjVMl977bUN1+cDH/owrFmXW42Oqmm6hh2/2467v/yPSPb0\n4jvf/J+492ufx9987FOLr5HLZfz3ow/h7i/da/vviaKIN735rQCAM7eehf6BQby4Zw/OOfe8qtdd\nedUbceVVb2wYZzZTavjc73+3HT/43r/g9k9/xfZyWfbt3YmZqaP48qc/ClifDQdMHj3sKiG/58Of\nQTov49FffB+P/uL7eOMfv7vu6+joZudRQiaki1Tu9Cpn1uvXr8f3vve9xeesS6b+8z//E08//TS+\n853vIBQK4b777sNTTz21+LpQqHpWd88992Dnzp14+umn8c53vhM333wz1q5d23Q5fL5jl9/wPF91\noxGO4xAOhxuuz5e/+Hls3/7Mksc5jqs7Qx4cGsLs7GxV68SpqUkMDi2dRfYPDOHMs89HssdMQq+5\n7Ap86m8/WPWaxx97CKMrVmPZ6KqGy9hKowqHNUOuxXHc4gy5np07fotv/P2ncesdn8fwyHI3C4Rl\no6vxsbu+uuSpn/7Hd/H0fz8McBze/mfvwpazt1U823xgdN7Fb8BXPvluvPGP3414Tz/SqenF52S5\nBEUu1T2pi3iHEjIhXeSHP/wh3ve+92FsbAzPPvssPv7xjyMcDmNsbAxPPPEELr74YgDAnj17sH79\nemSzWSSTSYRCIeTzedx///0YGRmpG1vXdYyPj2PLli3YsmULUqkUduzYgTe84Q1gjOGJJ57AJZe8\nCs899xzm5uawefNmpFKpJTOj2kFDM05nyMlkDzZt2oyf/uQBvOnNb8VDv/wvDA4OmeXqGq989evw\n8H/9BKViAcFQGM89/ThWrl5X9ZqH/+vHuOyKNy9571+/609xx933INnTt+Q5TdPw0588gDe+6S3Y\n+cIOzM7OYMPGjUte52aGvGvHb3HPF+7ELZ/4HFasWjoQsmPdxi2YnZ7Erh3P4oyt5wMADh/ch2Wj\nq/CHV1+HP7z6ugbvrN5WmXQKkiQBMAdcLzz3GIZGVgMARkbXwTB0HHzpBaxafya2/+bn2HDmBU2P\nH5P2UUImpIsYhoFrrrkGpVIJf/u3f4vh4WEAwL333ovPfOYz+OxnPwtVVTE8PIyvf/3ruPrqq/HQ\nQw/hqquuQk9PD7Zt24ajR4/Wja3rOm699VZks1kIgoDe3l58+tOfhiRJuOeee/DJT34Sn//85+D3\n+3HPPfcgGDSvK62dHVb+dyduCHHLbX+Lv/vEx/Ev//yPiEQiuP2OTy4+d9cn78BZ516Ms7e9En39\ng7j2T67HbR96F3hBQE9vH9510y2Lrz06dhiHDuzDq17zuqr4mXQK+VwWkTongAFAJBLBy/v24bp3\nvA2GoeNTn/7ckuPHbn3j//8MNE3D1778qcWZ9/v/5naMrlyD7U/9Btuf+g3e/X5zHf7XPZ/Dc888\njkw6hbs+/gEEgyF88evfQSgcxc233o1///Y38P1vfwOapqG3fxA3ffguoM6pL39/9y04cuhlABw+\n/sH/F4NDy/GRO76M1Ow0vnXvF6FpOnTdQLJvCNfeYFYYOI7Dtdd/EA9872vQNBXReA+uvf6DS4MT\nT9FlT3XIsgq/39uRYL1LTrozpvM7g50qMZ2cfNWJuJs2bcL27dsRiURavraypOuVTnym2YKMdo8h\n15qYLTS9YUUrT/zmYRwdP4I/+pMbFh8bTAYR8IuYOHoUf/anb8PDjzze9nLOZkoo2Lw0yS5F0VB2\ncAmZHdm8jHTe25Owgj4BV1+6rvULF9BlTyaaIRPSJej2g8fHxZdc1vR52g7kRKGETEiX2L1794le\nhNPe8MgIHvr1f5/oxTjtpGZnUC4dO+ZeLOSRydg/TBCLxT2vGJ0IlJAJIYScUIahQdfVxf/2B/x4\n/mAePN+61WOxkMflF60/JcrblJAJIYScUH0Dw1XHkE9XJ/8cnxBCCDkFUEImhBBCugAl5Dqs5g1e\nsWJ5GdO6Ws0wvLsEwuxUc6whglcxgc7E9HLdzXisAzENT7e7FZMxb29laG0fr2PyC40WvIyptnHJ\nUyPFsurpdtJ0A1OpgrffJ8aQLSie38KyrGgeX5gGSBKlFjfoGHIdoijAMAzoulftF7HYlq5RX1sn\njnUlEpr2ynXC2smLYvP+u85jsqrl9Lr9olcxK3v/Nurp60Rtq0QvWjpabQ3dtl9sFrOy/WK7MStb\ngoaDEmRFh6KZcduJmSso2DeWRlHWEQqKSEb8bZ9Zq2k6UtkyjqgGeqI+rBqOIxgQ2/rNT8zm8e8P\n7sLze2eweiSON16yHv09IbSz/sWSgt/vm8WBiRxiYQnnrO9HNLy0ZaMTsqJh5/45vHg4jaCPxxmr\nexHwt5cSAj4BPbEAkrFAW3FOV3RjkBbc7qBqE4dXMRslCretA5slCvcxqxNHvb/nNNk360/ttnd1\ns17SbvtMdzJmvYGH2z7TlYPF2u9TO72rG31nGGMollW4KZSUFQ1j0zlMzi29FWVvzI9QQAIcJlBm\nMOSKCjIFZclzq4aiGOwJOe74VigpePS5w/j+L/egdq962QUr8YotyxAMOLvhkK4bODiRxfbdU6id\nwK9dFsO65QmIorPlZIxhbCqHJ16YhF4TdLgviFVDMccDHUHgkIz60Z8MQVh479a19htd1N4YxImT\n7SYizW4MQgnZBnN2Z+5IW+2g7CYHpzs9uzNWu7M7J8nBKrvZjWlnnewOSpolDrcxzdfaG2xYfazt\n7KDsx7Q/0Gk2sKvkZAZuP6b9gY7d74iuGyiWNRg27l6m6QZSmRL2jWVhNNlNCTyH/kQAkmRvdleW\nNcxmSkuSZiVJ5LFhNI54JGDju2xg94FZ3Hv/75Ctk+AtAZ+At71+M9YuT7b+PjGGuUwJT+yYQK7J\n3b4EnsO5G/ox2BOyNSjJ5Mp4cuckUtnGd+biOGDzyiR6YoGm7SMtkaCE/mQQ4aCv6nFKyPVRQvZI\nq52em1Jnq52em1sktkq2laVkr2La3ckfr5iNBgVuy9HN3ue2HN1s27qd9TcblHQipptZP2MMsqIt\n3P5y6XsYY8gXFew7kkFBtn/ryUhARDzauIytaQZS2RJkB7ee7I35sXI4Zs7C6yzn1FwB//uXu/Hs\nninbMdePJnDVq9ahN1G/jF2SVezYN4uXx7O2YyYjPpy1vh+RkK/u84qiYffBeew6mLIdM+gXcMaq\nnoZl7ICPRzIWRE8sUHfbU0KujxKyx2p3UG4Sh72Y7R1zrJ3deXEcs3a53O7km8V0W9qtVLtc3RoT\nqK5+tFMuttRbrna/T/WWy4uYxZIKzTg2W5YVDePTeRyda31DiEZ6Y36EghKsZNesPG3X6uEoBnpC\nkBbKw8Wyisd+exj//uAeVyeDcQBe94pVuGDLCAIL983XdQOHJ3N4etdU04pAM+tH41gzEl8sYzPG\nMD6dx+MvTEDX3cVc1hfCiqHY4nYXeCAe8WMgGWpaLqeEXB8l5A6wdlCA8+OhxzMmcGzH2e7JT8cj\npiDwnjY5sAY6QHsDkfox2xuEVce0Zm2diOnduluDEi9jqqqOfElFKlPCS+NZT852FngOfYkAmAHM\ntChP2+UTeaxdFsPkXAH/+B/PYz5XbjtmyC/iba/fjHgkgKd2TiJbVFu/qQVB4HDehn74JAHP7J7E\nbLr9xhFWGXtZfwSDPSGEG8zEK1FCro+aS3QAx3EQBG8vFrBiGoa3XYesJOdV4uxkzMr/9yam4HkX\no2Mxveu0JQg8NE13fIJOq5hedwTjec7zdZckAXOTWew9kvEspm4wTKWWngTWDkUz8JvfH8X9D+/x\nLGZR1vCdn+/EptUDrk54q0fXGZ7eNQVV01FWvAnKGLDr4DxesWUIfh+ljU6hi8UIIYSQLkAJmRBC\nCOkClJAJIYSQLkAJmRBCCOkClJAJIYSQLkAJmRBCCOkClJAJIYSQLkAJmRBCCOkClJAJIYSQLkC3\nXCGEEHJCpWZnUC65u7NasZBHJhNa8ngsFm+7X/bxRgmZEELICWUYGnTd3X28/QE/nj+YB88fa0hS\nLORx+UXrT5r7W1soIbfBi45MS2PqC/ex9u4e0VbrQC/pXt14t4LVjpDZ6JVrP6bZVcDLmFZzBa9j\nchy32KXJC5quQ5Z1SBKDz2av4JYxNR3pvIyAJCAS9nsU08DR2QJ0TQcv8J58ppqm4Ze/fAixWAwX\nX3yRZ9tpMBnCpeevwCPPHfakYQUA+CUOqXQBsWjIs+XsjfkBjsOhyZxny7l2eQyqZsAneXuvfQDo\nGxh23VziVEIJ2QWrjWFlGzo3PXarY1qt/cwdkhfJvrYNnxftF+vHbK9DUWVrP8BKou03MDC3C7fY\nCIPjWNslLGtbCwIPwzBgGKztAVnldjEM1nYzDMYYSrIGTTMAjoMm61BUA0G/4PozZYwhW5CRL6ow\nGFCSdRTKGnpifkgukz1jDPvG0njx0DxyC12Ogj4BgsC3tf6/f+EF/PpXj+LAoSPgeQ47d+3GFZe/\nHitWrHAdUxK5hZ7IHM4/YxnWjfbg188ewr4j865jigKHoF9CvqigWM5BVlTEIiEEAq07KTXilzgM\n90Zg5eCta3sxlSq21WgjHBRxyVkj6IkHYTCz9aRP5CGKgueJ+XRH7RcdaNartp2+wFbiqI1p/T03\nO6dGg4R2evg2Sujt9PCt7QO9NKbzgU5tH+jq59wNdJoNutwOdJolXrcDHUXVUFaM+rN3xiCKPIJ+\n0dG2L5U1ZPJlqHX66XIAQkERyWj9JvWNzGfL+O3eaUynSqiNKvIcfD4eouBsh59KzeMnP/0ZXti5\nB4paXf6MRkI45+yt+MOrrkIgYH9mzwGIhKS6250xhrGpDP7zkZdQVjTbMQEgGpSgaAZkVa96XBI5\n9MRCiISDjgY6HIDhvhACPmFJ1ygOgKYbODCRQUm2X9niOeCCM4awciha93sqCRwkSYDY4Dt8vNov\n1tPNLRmpH7IHGiWOpa8zYLenbbPEUcsq57aOaW+27iSJ2E1iTmJWVhma7XSdDHTsvtbJoMTuazsZ\n085AR9d1lGQdeovWnVaiDvgE+KTm31HDYJjLlFBW9KavA8wkGg1LiISaJztNN/DbF6dxeCoHRW2e\nHPwSD0ngIbRoSanrOh566GE8vf05zKXSTV+7bHgQr3rVxbjowle03E4hvwifJCwZMNRSVQ3P753C\nI88dbvFKIOgXwfMcCqXmx0sjQQmJWAjhUOuBTjLqRzLiQ53xUhWeB3IFBQcmWpexV49Ecfb6fgT9\nUvOYHCAJPHy+pYMnSsj1UUJug5uZb6sdqdvZdLPE6Hbm24mYzWZ3bmfTrQY6bg4btBpodCKmm9l0\ns/fUlqftYoxB4Lm6Zeza8rQTflFAMu6DJC6d3b08lsbew2mk87LteByAQJMy9q5du/Dwrx7Bywda\nJ0OLIPCJOQLCAAAgAElEQVTYvGEdrrjiDVi+fPmS5yWBQygowel5HOlcCQ8/fQAHji7t6ywKMMvT\nJdXRMd2eWACxaAgB/9IytiRwGOmPgANaDhoqcQAmUwVMz5eXPBcKCLjkrGXoTQQdRAQEnoNfEiAI\nx/YVlJDro4TsQjtlWEu9xNvu8eZ6SbJTMQH3x5vrx7RXZWgVs3KbOKkyNFK7rl4cv+9EzNqBjqLq\nkBUdRjsnlzEGSeQRWChjl2UN6Vz98rRdHIBQQEQyZs7uMrkynntxBlOpoqPEUUnkOfgkAaJonmMx\nn07jpz/5GV7YtQdlWXEVMx6N4Jyzz8RVV10Fv9/XtDxtF2MMhycyeOCxvZAXKgvRoARVN2xVGuqR\nRB49sSAikeDiQGe4N4SgX4TudMS0gAOgagb2j2cga+b+44LNA1g1HG/rOyoJ5nYSBJ4ScgOUkB3S\nNH3xZCAv6LqxmJi9ui7OmjG2k+COR0xrdge0Lk/bj8kWz3T2MuaxY9bexLQGEIC3MXXdgKzo0FqU\np53E5DkOZUVFWfHu7HlR4HB0Jo9DkznILcrTdvkkHk8+8QQef+JJzM65P6Gq0uiyIVz/Z3+CdWtW\nuh4w1FIUDb98aj+OTGWRb1GetisalLBiOImVw/GW5Wm7eB5gBsOaZQkEA83L07ZjcuYgYtvmQdvv\noYRsOrmumj5O2j3LtZYg8G2fhV0vZuX/exfTu2QMHFtnwaPLWcyYXEdiCgLnaUxrUOdVMq6M2epY\nsdOYDIDsYTIGAE1nGJ8peJaMAUBRDezZ86JnyRgAjoxPIuAXPUvGAODziZAkwbNkDAC5kopouPWx\nYicMAxgdjHmWjAHAYMcuNyTOUEImhBBCugAlZEIIIaQLUEImhBBCugAlZEIIIaQLUEImhBBCugAl\nZEIIIaQLUEImhBBCugAlZEIIIaQLUEImhBBCugAlZEIIIaQLUEImhBBCuoD9DtinEUHg6jd4d8ls\nhOBtTGDhHsQexwRYB2JisfNTN8dkzOrO5d041TDM+zh7+XkahuG0M2BLumFA8/ge7owxqLq398cG\nAI73drfF8xzyRXcdo5oJ+ERwHBy1W2xF1w3H7RZb4Tl4HlN0+D1Kzc6gXCp58rf9/gBKpYInsY43\nSsh1iKLYdqtAS2UfXy9aBVoxrWYV5r/bTyLHeu4KFcvcbky20C6Qh2EY0HXnvZUbxeR5DoyZn0W7\nMStbRQLdH5PjeIQDIkqy3naTCcYY8kUFuw+mkMrK2DCaQDIWaHugky3IeGrnFF4ez2D1cBTRkM9x\nb+V6plIFnHHB6xGK9uDAvt1IZ5b2Hnaiv68Py9ZswXP7ZcCXwrrl8YY9t+0SeQ7hkIQ/vWIzVgxF\n8dhvj2AqVWwrZizsw6rhBFYMJwAwqJrRdtOOgMRj7WgCF505jFS2jPHpPIqyuxaRFoE3ezivWeas\nc5NhaND19htxlIoFXLBxLeLxEcRi3nWPOl6o/WIT7fRErtcL2WImUecx6/UYro7pvKNUs5jHkrS7\nmPXW0e1A51jMpevYzkCnUZ/idvoXN/rc2o/JliQLRdVQVgxXVQ1F1XF4MosXD6erHo+HJaxZlkA4\nIAIOY6qqjpcOz+Ox309UJeCgn8eqoThE0fm68xyQKyo4MJGrmm0W8hnse+EpHD64H4rqbGceDoWw\nbOVaLFu3DaLkW3zcLwl49dkj6O8JwmkZwuoDHY/4qmaIJVnFj369F8/vnUZR1hzFlEQeywei2Lxm\nAOHgseW0fg+KqjvuXc0BWNYfxkVbh9EbDy4+bhgMhyaymEmXXPXDjkd8GB2IIB7xO36vV+0Xu7nt\nooX6IbfJ2sHameE0SxzVMRsn7GbL0Gxn3iy51mMnQbiLuTRx1Itpd1DSqZh2BjBOBjp2BzBWGdte\nzGNVhkYYYyjJGjTNsJVADYNhLl3C716agaI1nmWtGIxguDcMSWo9Y2SMYXKuiIefOYxsqXHSGeoN\nYSARtF0e1TQDByczKMmNl3N67GW8vOe3ODox0TIex3FYvnwFlm84D5H4QMPXjQ5GcN6GAYSC9toS\n+kUesYgPQX/jouOB8Xn85DcvY9+ReVvrP9gTwvoVvRjujzV8jW4YMAyGks2ZbSLiw1nr+rBpVU/D\n33OxrOLA0SzSeXtlfL/EY7g3hJH+iOtqDSVkEyVkB1rN7uwkDqcxDcNwPPNrlUTczHxbJW+nA4zK\n5Wj0Hncxm7/H6QDDznvaidno83RTndF0HeUmZWzGGAolBbsPzWM6Ze94ncBz2LgigWQ0AK7BcuQK\nCp7ZPbVkpt0Ix6FlGZsDMJUqYmre3nLquo4Du5/BwZf3IJPN1X1NX18flq3ajP7Rzba2E8cB2zYN\nYPVIrOFvWuQ5hIMSYmHJ3sCaMTzy7CE8/vw4pufrl7GjIQmrRpLYsLLX1m/fOvehWRnbLwlYsyyG\ni7eOQLJZpZiaK2B8poCSUj/Z8xzQGwtgzfK442PGtSghmyghO1Rv5+smcdSLWbnzdbOTr6VpBnj+\nWGL2ImZtMm+nrG+pl+zdluCPvX/pQKedkrEVs7Y07rasX6l20OVmYFdJVjXISvWOWVV1HJnOYffB\neVcxExGzjB3yHytjq5qOfUfSePT5CVcN6cN+ASuGYlVl7EblabsK2TRe2vkkDh86AFU1Z+rhUBAj\no2swsm4bfP6A45gBn4BXnzOCvkRo8TEOQNAvIBH1u0pGhZKC//j1XuzYN704uxUFDssHY9i8uh+R\nkPOyL2MM+kIZW1soOXMARvrCuOjMIfQlQ80D1GEYDAeOZjCbLkOr2MaRoIiVQzEkos6Xsx5KyCZK\nyC7pNWePenF2qpXYrTMzvY/pfidfqbIs73VMQTBPVPNi3SuXE3Cf3GtZgwXDgKtjos1i2j000opV\nxpYVHals2SxPt3kSEACsHIpiMBlEKifjV8+O2S5rNjPcG0RfIghNYzg8mUWhzROLAGDqyF7s2/M8\nRNGH0fXnIpIcajvmquEozlnfj3jEh3jYh2DAXjm7mX1HUvjpf7+MXEHB+hW9GBloXJ62yzqB0icJ\n2LquF2es7m37+1QomWXssqJhMBnE8sGop1cOUEI2UULuQp25RMh56ftExOwErxL8yRhz+85JvDTe\n3pnItdLZEo7MtHfWcC2fyEHRvN0VGZqGXFn3NHH0JwL4/950hqcxy4qG7bun4OW1bIwxXP3atQh5\nMGiopGk6RLH9AXgtSsim7t+bEk90YthFQzlvdWJszDy+XhkADK8vgoa318BaeEHw/Hp6Bm+vKQcA\nnuMgeDyw5bj2L9msx+uJAqlGCZkQQgjpApSQCSGEkC5ACZkQQgjpApSQCSGEkC5ACZkQQgjpApSQ\nCSGEkC5ACZkQQgjpApSQCSGEkC5ACZkQQgjpApSQCSGEkC5w3BPyXXfdhcsuuwybNm3Cnj17Fh+/\n7LLLcNVVV+Hqq6/GNddcg5/97GeLzx06dAjveMc7cMUVV+Dtb3879u3b5+q5l19+2dN1MQxjsbet\ndzEZvL6RYEduyXgax+wE3WA4MJGFrDhrYN8MYwyiwEMQvL1HcqmsehbPilkoqdD09ptKVPL7BIT8\n3t53ec1wFF7fkZLjOPTGnXehakbgOUzM5D39/muaDkU1Tprf1MmocTftDrnyyitx44034rrrrqt6\nnOM4/P3f/z02bty45D2333473vGOd+Dqq6/GL37xC9xyyy34wQ9+4Pi5j370o4vPtaOy5SBgNgVo\nt0NPZUyO4zyJaS2b2cbQu5jWIMSK2U7rxWPLabVL5Npuvbg0Jt9268VjMc1l8zLm2HQO+8ezyJdU\njE3lsXI4itUj8ba2UyZfxnSqBFEUsHFFEvO5MiZm22sIUSormMvImM8r8Es8OI5DuUGvXLs0XYes\n6EjnZPglAZGQBJ9PBN/Gugs8kIgGYBgM4aAEXTMwNlto697rkaCEt79uPdYsi4HnOKia2Xvai9Qk\niTzWjyYw1BPCi4fnG/Y0tisakiAKPHYdnMdUqojNq5KIRdwnfKtzmKYZYABUzUDAJ0CSvG8ycbo7\n7jPkbdu2YXBwcMkoy2qyXSuVSmHnzp14y1veAgC44oorMDk5iSNHjrh+rh26ri+2CeR5MxEJAg/D\nYAsJoP2Y1o3hDYO5noHrurHYPYjn+cWYjLElrSOdxuT56pjWc26YreLMmFYs8//NxOxmNG5ui6Ux\nrQGEm5jW52Zuc29iFooKnt0zhR375pAvmbPOkqJjz6E0ntwxgVSm7Dimomo4eDSDw1MFlFVr4MSj\nNx7CxhUJRMPOu//ouoHp+SIOTxUwv9BuUVYNlBUdQZ8An4sZuMEYyrKKdFZGKivDYOa6z6TLyBVk\nqJq731Ii4kcyGoSmMxgM0A0API/VwzH0uZiFchxw5cUrcfOfnoP1owkIC997nyQiHJTgk7zZhXIc\nh1jEj/M2DmDtspir9h1Bv4Bk1A+e52G1Lp7Lynhq5xR27Jt19RstKxpyRdXsr7wwWWAAirKGQlGh\n2bLHjvsMuZmPfvSjYIzhrLPOwgc/+EH09PRgYmIC/f39VbOl4eFhHD16FJFIxNVzo6OjjpfNakRv\nJaJalcnO7uzO6lXcLKbFbms+a6bdaCZsLZe1Pt7E5ABwCzHt9UeurAjUK6laMc2diGG757I1Y6+3\nXtbfMl/DbM/AK2fFjWKahy+Yrc/TMBhePJTC+GyhYY/i+byCZ/ZMYagnhC1reiG2iMsYw1SqiPms\nXNVIvpIkmU3lCyUVhydz0Bu8rjJmNi8jlZORL9UvpZcUHQJvJoOSjT7GjDFomoGirCJbqF/6zhZU\n5IsqElE/ApIAwUa7v5BfQDgoQdEY1DqJR9UZggEJq4ISpuYLKMmtk9OmVUlcddFK9CWCDX+fAZ6D\nJDCUFa3l52mHIPAY7osgGQ3g0GQWM+nWgzKeA2JhPxiAeoug6gxHpvNI5cpYMxzH6FDj9n8WTddR\nkvWqSmAljuOgMyBXVOATefh9YlsVndTsDMqlkuv3W4qFPDKZEGKx+EnRGrZW1yTk7373uxgaGoKu\n6/jyl7+MW265Bffee2/d1zYblbl9rtl7miWOSsd2zqxlebjZTr4eOyVnJzF5nq+a9TWK6SRxV8Zs\nVsauLCW3Uj3QaR7Tbsu52ll9o/c4/TyB1p/X0ZkcXh7PIldsfRxW1xnGZwqYz5axciiGVSOxutsp\nW5AxlSrZLB9zCAd92LgyiVSmjMlU/TJ2SdYwlykhnVNalmV1AyjJulnGBoeyWn85dF2HohlIZcp1\nE0clgwGprIygX0A0aJax6w4GOSAZM8vTdvop6wwY7I1AVXUcbVDGDvlFvP1167BueaLltuc4DqLI\nISxInpaxA34RG1YkMdQrY8+hNFSt/gDCKk/bGQsUShp27J/DxFwem1b1Ihb2LXlNZXnamhE3x0FW\nDaiaimBAbDlwbMQwNBh6++cmBAJ+PLlzEolEvKt7IjfSNQl5aGgIACAIAm644QZceeWVAMxZ7czM\nDAzDWNzpTU5OYmRkBOFw2NVzTthJxLWs2V0zTo872lmOTsR0Osq0t5zOjj11Iqb5nubr5ubYcKPP\nqyir2HNgHjPpIpxWDouyjt2H5jGTLmHjyiTiET8AQNV0TM4VkS0otnbItcvZlwwhEQ1gfDaH3MJs\nVTcY5rNlpHIyZIfHh61jn+GACE3TIS8kSMYYVM1AvqigUHZ20lpJNmdqiYgfoYBYtU2SUT8kkXd8\nzFXXzerImmVxZHMyZhYODXAALr9wBV6xZRBBv7PSvlXGliQBiqwvGZRwnPP+4RzHIR4J4ILNg5ie\nL2LfWGbxuaBfRCggLpbmnZjNyHhm1yRG+iPYsCIJYWGQq6o6ZNWAwczytJPlZACKZQ2SyCHgYra8\nYuUqxBMJR+9pJJfNoLc3imSydSWg23RFQi6VStA0DdGo+QH++Mc/xhlnnAEA6OnpwRlnnIEf/ehH\nuOaaa/Dzn/8cQ0NDi2Vnt881Y82cvDgBypphW7yICVQfs/UqpjW78z4mA8B5cvIXYK27FbP9k7+O\nxTy2H/IiprXuLx1JY3y6ALnBLMeu2UwZ6Z2TGOoJoT8ZRDqvmMf22iCKPFYOxZAvqtixbwZzmTJy\nDcrTdhXKGsSFMnY2L6Mka8g0KE/blc7LyBVlxCN+JKJ+JCJ+KBpr6wQoRTUQWChjB/wCrrhoJQaS\noba+9xw4+HwCBIFHqazCWrp2DrXyPIeh3jDiER/2j2fBmPntb2fby6qBA0ezmJkvYe2yGOIRP/QG\n5WknVI1B1cwydsDBoKZYkiGIzs+ZqKdQKGNuLgdd74r0tkRfX+OBAseO81H522+/HY888gjm5uaQ\nSCQQDofxT//0T7jpppsWd2Cjo6O47bbbFmezBw4cwK233or5+XlEo1HcfffdWL9+fVvPNSPLGvx+\nbzem3WPAJzpmZUXBKyfLujPW/g6pVrGs4pHnxj29kI3jgOUDEbSqwjj148f2I1fy9pKmdK5sqzzv\nxNa1fR5fGAhc+9o1GOwNexqzWFKgtjlgqjU2ncN8TvE05rrlMQz1RjyNaRgGElH7J9H9y/95CpFo\n3JO/nc9lcMnW4a4tWff3N07Ix30Iceedd9Z9/P7772/4ntWrV+Pf/u3fPH2uuU6MUU6OmHTS5EnC\nLBB4y+t4QFuXLzWMycNx2b+VDiymeYDb44Ts9YCxY2g/4srJdxoaIYQQcgqihEwIIYR0AUrIhBBC\nSBeghEwIIYR0AUrIhBBCSBeghEwIIYR0AUrIhBBCSBeghEwIIYR0AUrIhBBCSBeghEwIIYR0AUrI\ndXjRAKFWZ25514nl9DwkAHetL5sxu+d4G5Mx72MC5q0ePdWh2xJ2Yt01r+9xic7c3rUTH6nh8W0z\nAZw097Y9We7w2W0oIdchigJ03ajq0uSW1RuZ47iFmO3voCr7GHsdk+M4GIZR1U2qG2MCZkwv1h0w\nm1VYnbm8jOmXBJy1tg/RkLN2fo34JR7DfSGEgiJEjwaOmqZj/1gaAschEvTm9vaSwKFUKiOVySHo\n4+FFH5BIUMK5G/px9vo+DCaDnsT0STxWDUVRlHUUS6pHv3kDc5kSdh2YQyYvg3kQE4xB0wyEQj7E\nQtJiy8R2cAD64n4M9UYgCi76Q9ZdTAYOQCjgzff9dNOd/alOMKv/rplEmKtWhNbOvbLBvRnzWDJ1\nM2u2klplzMoE7Sam1XbRislxXsVkFX2KhaoE7aYKYbVdrIxpPd5OzMptVPu4m85XtZ/ncH8Eg71h\nvHg4hfHpAhQXbRgFHoiH/RjqCy/ujCWBh6zqUFTDcU9cwPyOzmXK+O3eGaiaAfA8eMYQD/ugaGYf\nYjfLqWs6dh+eM5vcA5idzyEa9iPk96PoMuaKoRguOGMIPTGzg9D6FT70ZQIYmykgU3DX/ag/EcD6\n0SQSUbO/9EymDL8koCfmgyQKrn7zxbKKA0czSOfNDleHp/II+UUs6w8j4BNcTR0Nw0BJ1qHqDBw4\nxKMBBAM6cgXZ1ecJAJGAiNUjcYwOHes8pOnmNjdctmHkOMAn8vC76IdMTMe9/eLJSNd1AJztdn9L\nE0f9mGYSsR+zVYJwmkRqE0ejmEDz11THZAuJuPHrrb9rN9lbMZu93s5rKlkDpmavt/Map68vFBXs\nOpjCbLpsu0waCYoY6Akh3GDWoRsGZEWHotn/KRdLKnYdnMP0fP0etIyZn2dZ1qHarGyIPDA5m8Vs\nutjwNX3JCBjjULbZx3ggEcDWdX1Yv6Kn7vOGwTA+ncPUfAllxV5yigYlrBiKYsVQtOF2SoQlREJS\n099wJVXVMTlXxKGpXMPXDCSC6I0HIIr2fkuMMSiqjpJS/7MyBwAaCiXFdl9oSeAw3BfG5lU9DX+j\nZUWD4qDPNGMMIs8hFJRcJ2Jqv2iihGzTsRlv45mY06QAtJ7dWT16nfTqbZWYnSYaoHXytvP5LF3O\n5gOdyiqD/YFL68GT00GGndc7jTk+ncP+o9mmvYL9Eo+eWAC98YCt7aRqOsqKAb3JdFnXdRyZymPX\nwXlby8mYeegmX9IavkYSOOQKZRw8ai+mJPFIRMMoK41n9uGAiHWjCWzbPATJRgIrlTUcnsphLlNq\nGNMn8hjqC2PjiqStmDzHoTfuR9DfeMZnGAzpnIy9R9K2jpfzPIfRgTCiIV/jbcoYNJ2hIGu2qsgG\nY8jmZRTLatO2lL0xPzav6kEs4m8ZkzGGkqyZVY4mA1ae4xDwCZAkewOXRighmyghO1RvducmcVTH\nrJ/Ine7kKzVKup2L2bwi0CpmbSLvREzr2LCbbWQtU+02tlNlaBjPYHjp8DzGpvNVZezF8nRvyHFc\nxlj9MjZjSGXLeO7FGcclc3MXwaCqBkoVs1CeM9f/wNis7RlapWg4gIDfV1V25Tlg5VAU2zYPoTcR\ndBxzLlPE+EwB2UL1QKc/HsDa0cRiyduJoE9AIuqDTzp2hI8xhlJZw8GJDFI55yXzcEDESN/SMnZl\nedopWTXL2LWHGsIBEatGYlgx2Lgi0Iim6SgpdcrYjMEneVee/uK9P0YoHHH8Pr8/AK5mAlAs5HH5\nRespIZ9OrJmYyV3iaBbTbXKvF/PYwMFd4lga09z5WjN3t8eZK1UmtnaOXVfHPDbQcVoRaKRyUOJV\nzFxRwe4Dc5jLyAgFRAz2BBEO+tqKqRvGQrmZoVRWsftgCpOpUlsxrQFNSdbAgWFyJoeZdKGtmADQ\nm4iAgUM07MNZa/uwfkWyrc/UMBjGpnOYShUhiTxWDsWalqftSkR8iARFGAYwlSri4GTj8rRdA8kg\n+uJ+8DzftDxtl3UcO19UYBjAcF8IZ6zubft3b5WxrfJ0wC94ss+zfP5//geCobCj95SKBfzBtrWI\nx5fOrGOxuCf7z06ghNwh1kfn5QkM5rE77y+9MgzD8y+orhueJPhO68RydiLmwfEMeKH9BF/p9/tm\nsHP/vKeX9cymctg/lvI05nmbh3DJOSttlZLtUlUd0bAPvjbLqZV0XcdMumyeBOcRUeAx0h8CY95t\nd8NgWDkUXTxhzQuMMaiqDp/P+3OB3ZSsu7003UizhNz9e9MuxnHe7jytmJ1Aw67uFw55f3aqpjHP\nr7Fl8P663ZBf8jQZA0AoIHqajAHzMIOXyRgwjwF7/fvkeQ5hjy5hs3AcZ/uENOIOfbqEEEJIF6CE\nTAghhHQBSsiEEEJIF6CETAghhHQBSsiEEEJIF6CETAghhHQBSsiEEEJIF6CETAghhHQBSsiEEEJI\nF6CETAghhHQBSshtsHrGeh2zE6hfuHfYQrs7r7dVSda9/z55fpNLQOA5z79PksB5vu6iwHu+nMWy\nCllt3IrSDV0zUFK8jclzAAfvf/R0C97O8v4u4aeJ6m5PhufdnsxOQt52e/KqIUJltyfvOjN1ttuT\nVzHTuTL2HJrHfE5GMurH5lVJxCPOW/pVKpZU7J/IIpNX4JcExCM+sy1fG1RVx8RcEX5JxJbVSYzP\nFJDOO28TWCsg8ejvjaI3EcahiXlMzLTX8UgUeFx2wSqsGIqjVFYhiTxEUWhrO3EwuxwlIn4wxpAr\nqsg26Ttth2Ew7D44h/3jGTAGDPaEMNwXbms5rRaOhbKCmXQR/ckglg/E2m4s0xPzoS8eBM9392+e\nLEXdnhyifsinZz9kXTew68AcJuaK0Cp61UoCh6HeMM5Y3eP4MzUMhsNTOUzNFaFVNC/mOSDoF5GM\n+h3vnBljmE6XkM7KS/oel2UN+49moRvOf/I+0ZxtVvY95jhAVVTs3DeFsqo3eXd952wYxFkbBqv6\nDAOAX+IhiYKr72gi4sNAMgi/r7p3saLqSNX5TOyYmMlj14E5TKfLVY/3RP1Y1h9GPOp8QKaoGvJF\nFYVy9cw4GpIw0hdx1Qva7+OxrDeMUFDq6t98PdTtyUQJ2aZGO/lKjRJrM2bT+8YxGWOLfYedxWyc\neBr9yJqpnME2i9lsXZYup1kRaB3TfhJtFdN8jf0dFGNm0jx4NLtk51nJaRP46VQR4zN5FOXGiUwS\nOISDEqIhyVbMXFHB9HwJxSbLCQDz2TLGZuz1MeY5wCcJKCuNl1Pggbl0EXsPztgqkPcnA3jteauR\niDVOOjwP+EQBPsnebFkUeIwOhBEONv6sDIOhKGtIZcu2Sq9FWcXv985ibCYHVav/BlHk0B8PYnQw\naquzlGEw5IsK8mUVul4/Js8BPbEAVgzHELDR6pDjgJHeEGJhf8NuTG5/80Dr/YiT33wjlJBNlJBt\nsLOTr35969Gjm5itEpOd11RqlWStmID90bU1KGn2+npVBjsxm73e6WDIzg4qm5ex+2AKc1m5ZTxL\nX9yPTat6EQv76j5fklXsH886Kh8HfALiYR/8DcrYqqZjcq6IbEGB3cmvrhsYm8kjW2hcyg34BGi6\nUVURaIaDgUPj85iYy9d9XhA4vO6C1VgxFLd9UoMkcPBJAkSx/rpzAIZ6g0hGA7a/o5pmIFtQkCvV\nX3eDMew5mML+sTRyJXvHdiMBEYO9IQz11i9jM8ZQkjUUSmrTwU2lgMSjvyeEZQNR8A0+r56oD32J\n6opAM535zbeO2QolZBMl5CacJo5KjWZ3bmbRler9WNyMfivV+0F5E7N6UNLuiLrRQMfpQKTVe3Xd\nwO6DKUzMFqDaTEaVJIHHcF8Im1f3QFiIazCGQxNZTM+XbCe4SjwHhPwiEhVlbMYYZtIlzLssxXIw\nZ4EHjuaqytj1ytNOllOWVbzw8hSUijL2mev6cd7GYdfN7euVseNhCYM9IdvJqBJjDIqiYy4nV/U3\nnpwrYOf+OUzPl1wtZ2/Mj5H+COIR/+Jjimom4rzN5F4rFpIw0h9BT/xYRcEv8Rjpa14RaKYTv3nA\nnGi4KWNTQjZRQq7Dy1JMZQJu5zhzveWzYgLtjU47HdMsuRtwUhGwG9PcRt6dtHJ0poADExnXO89K\nkYCI1cviCPgEjE03L0/bJQkcIiEfwAzMpMtNy+hOpDIlTMwW4fM1L0/bJfDA3HwBs/N5XHrBKiRj\nIZTIe5sAACAASURBVE9i+iQBQb+I0cEoIi6TUSXDMFAs6zg6m8fv9s7gyHS+KkG74RN59CWCGOkP\nQ1F1FEqqq0FYJYEHemJBrByOYtVQDPGoD2Kbx28rf/PmFSPe/uad7DspIZvoLOs6NE2HJHnz0Zhf\nSg6G4c3ZjoB5pqMgcJ6dQVkZs1PLyfO8J2dlVi6nVzEBc0c0lynjhf1znl0olC9r2Ll/DrGw37OY\nqs6QypZRKKmuTs5qpCcexFym7EkyBgDdABLxMC7augySjWOrdmOWZB0bVyTNQYkHeJ5HJMTjty9O\n48BEe2eMWxTNwNHZAqQGx3Pd0A1gJl3CWet6XZ3wVU/tb8nLmOYAl87CdooSch2Ghzs6S2cKEZ1Y\nTs9DAoDnl0hYhxK8jWl4/okydGIrdeb64k5cxuJlUrJ04mqbTqy7wHHQPf5Bdeba4hO/v0vNzqBc\ncnaYoFjII5M5VnmJxeKeDSxOFErIhBBCTijD0KDrzq4V9wf8eP5gHjxfRLGQx+UXrT/pyte1HCXk\nP//zP8d999235PEbbrgB3/rWtzxbKEIIIaePvoFhx8eQT0WO5vc7d+6s+/iePXs8WRhCCCHkdGVr\nhvylL30JAKCq6uK/LUeOHMHIyIj3S0YIIYScRmwl5JmZGQAL1z0u/NuyfPly3Hzzzd4vGSGEEHIa\nsZWQ7777bgDA1q1bcd1113V0gQghhJDTkaNjyBdeeCHm5uYAAIVCAV/5ylfw1a9+FeVyucU7CSGE\nENKMo4T8oQ99CJlMBgDw2c9+Fk8++SS2b9+OO+64oxPLRgghhJw2HF32NDY2hjVr1oAxhgcffBAP\nPPAAAoEArrjiik4tHyGEEHJacJSQBUFAPp/Hyy+/jP7+fvT19cEwDJQc3mGFEEIIIdUcJeQ/+IM/\nwA033IBCoYBrrrkGALB3714MDg52ZOFOnE7cg/VkiXkaO5narJxMy+qxTnzrO3ErUu9vxNqZ24bS\nvql7OErId955J+6//35IkoS3vvWtAIBMJoP3ve99HVm4E0UU+YWGCO7bkFms7icAPItpxfI6pqJo\nyJVUBP0iAj7Rk3tFa5oBWdMg6mb7PC9iqqqOfEmFJPII+kVPmmGoqo6ioiHoF6CoOvT2Gv4AMLf9\n/rF5iAKHzav7G/b0dRrz6Ewec5kyRgcjnty7l+fMLkoj/WFMpYqedLoSBQ7L+sIY6AkiW7DfA7iV\nkF9EJq9AEnlPGsAwxiArOjaMJlEsaZhy2Xax1lBPEKMDUeSKCuZz9vtpN5OI+lAsKyiWzd9ot+5H\nDMMAx53GI8Y2UPvFJnRdRzstA+v179V1va2WgfX6IbfTD9h6f7GsIp1XFh8L+ATEwj5XvWYBQDcM\naKoBuaKVHc8BfkmAKLrr0mQYBkqyjnSuDKv/hyTySET88PsElzEZ0nkZ+8Yyi233dN2Aqumu+gFb\nUpkiHtl+EHNZ8wqEaFjCm1+9AcP9UbidPWQLMp7eOYGZtLmDl0QeF2waQCIWcL2cPpGHJPKLgwVN\nN3BkMoeZdMlVj2UA6I0FsGVND5YPRACYn/FUqoh0TobmsnGLT+IRDfoQCkqLjyUjPoSDkuvfp6YZ\nyBYU5ErmPZQZY9hzKIWXxzLIFZ3dV9kSC0lYuzyBjSuTCy1CGaZSBUzNFlBw2X4z6BewrD+CdaMJ\n8Avf8WBARCzkg89lJ616/ZDr7VucctuBzk37xUonUytGz/ohq6qKr33ta/jRj36EmZkZ9Pf3461v\nfSve8573wOfzph1at3HT37OyB3KjJGEmUfsx7TQPd5qYGWMoyxrm8zL0Bv1a42EfQkHRdu9Vxhg0\nTUdZaVywk3gOPh9vu5G51Uw+U5AbJslIQEIkLEFyMAstlBQcmcpjLlt/BqNpOhRVh+qgl62saPjt\nixN4Yd9M3ee3rOnDJeesQCTsr/t8PaqmY8/BFF7Yn6r7/FBPCFvW9DgaPIk8B1+TwVGuIOPIVB4p\nB7O7kF/EmmUxnLmmt+73uixrmE6XkKkY+LUi8BzCARGxiL/ucgo8h96YHwEHM0bDMFAqa5jLyXW7\nm5VlDb97aQZjDnojSyKP0YEIzl7fj4B/6XbQdAOHJ7OYS5dsf58EHhhIhLBxdRIhv7TkeQ5APOJH\nKGC/SmRnP1IvWduJ2U4ip4RscpSQP/OZz+C5557DTTfdhGXLlmFsbAxf//rXcfbZZ+PWW2/1ZGG7\nlfUlbfZFPpa87SVFO4nbYnfkaecHBwCKqiNbVFCy0eBe4Dkkov6WZWxNM6Bour1m7IzB7xNalrE1\nzSxP25mxcByQiPhblrFVVcd0uoRDE7mWR/kYY1BUHYqmw2iyb2aM4dDRNH61/WDLPsU8z+HyC1dj\n0+q+5oMSxjAxV8Bvnp+AZqOGfuaaHowORME1+Tyt8rQo8hBafEcZY5iaK2IiVUChSRlb4IFl/RGc\nu6Ef4eDSxFEbcz4nYy5dRlltPmMM+QVEI374bAyyQn4B8Yi/6YzR2paprGxr9j8xm8euAylMtyhj\nDyaDOGNNL4Z6wy1jZgsyxqdymG8xKEmEfVizPG4rpihwSERaD0qcJFq7+xEzJrM9uG6EErLJUUK+\n9NJL8cMf/hC9vb2Lj83OzuLaa6/Fo48+2t5SniQalbHrlae9iOm2FN2o/GSWpzVk8rLjU06CfsEs\nk9XMxAzDgKoZrkq8jcrYhsFQkjWkczIMh0dVGpWxDYMhk5fx8njG8bJqugGtQRk7nS3i19sPYjbj\n7AY5yZgfb3r1Rgz0hFBbxs4VZDy9a6plMqjlE3ls2zyARHRpGbu2PG2XqumLZeza2V1vzI/Nq3uw\nYrDxTqYew2CYnCsgXVCWVGf8Eo9I0IdgwPlx0kZlbE0zkCsqyDosRRuMYc+BFPaPp5GrGZREQxLW\nLotj46qexVKyHYyZ6z41V0RRro4Z8AlYbpWnHZ5vEQqIiNYpYzud8VZqtB+xJhNenL8BUEK2ODpA\nqGka/P7qUpvf719IKKcHQRDAGFssOQOomOW6+3LWxuQ42BqdNo9pLouV1DmOgyxrSOdlRyXYSiVZ\nR0kuIf5/2XvTIMmq+8z7d/fcl6rK2qt6X2gENDQwEiALEEjC2i1rvI0thbFn08TYMTEeWYyD1zOj\nMFIorJkv1quwZOm1pQFkIclawLR2DGIX0EDTC/Teta+5Z968y/shK4tasjLzZt6SCvX5RRBCebP+\nnMy89z7nPOfc84SrNz1Zlqr2dMWpa/21guNC0bTRbAddk5FlGbNik86ZlJuMoDaiYjnMLBaJBDUi\nQQ1NUyiUKlyYyjKbbm+BjarIKLKEIttULIeK7WKaFkdeneLIyam2ai5kynzlwRe5ck8vN1w1Qjio\nU6nYnDy/wIun5tqqaVoOj780yUBPiAPbqzZ2M3u6GZqqsHM4QU8yyMXpHPOZMiFDYftgjCt29aC0\nsVBPliUGUxGSMYupuTzZooUiQyigEYsYngRuJQu5quh2x6uOjutCoWwxnym1dY7KksSBnd1sH4rx\n4skZLkznkCQYTkW5am8PwTpWcjMkSWKgJ0JPIsiFyQyz6RKO45JKBrlsW9eqeXIvFEoWxZK1bGPL\nsrR8H2l3MWXtPrLSIaxN4fklxoLX8TRCvuuuu5iZmeHP/uzPGBwcZGxsjM9+9rN0d3fzV3/1V5vZ\nzi2Js+Rh+rHS9fWaLuD6WtN1XeazJQo+rJ6tocgS8YjR1J71houLSybX3oKaetTu6+encm13Gtbi\nui4vvTrNT54925KV3AqKLPH263dy4kK65XnLZkjAzYeGSCVDTe3pVnFdl0yuzPbBGNGQP+tGXNdl\nZrGIi4TR5iKlegQNBdtxMTtYnLeWsZkcEjCYivhWM5Mro6lVkfYLTZHoSQZbXvvRCn7MFW+EGCFX\n8fTN3nXXXXR3d/OhD32I6667jg9/+MMkk0nuuuuujhv5RkSWZV+Fs1pTwu9n+CRJouijGANLNzq/\nnRHJ104DgOvC1FzBNzGG6vd5cSrtmxhD9fs8eX7BNzGG6qPKluX6JsZQ/ezbB/wT41rNWEj3VYyh\n6uj4KcZQnSv3U4wB4lGDgRbmir1QsV3fnwSuuXeCzcOTZR2JRPjUpz7FPffcw/z8PMlk0ndBEggE\nAoHgUsSTID/22GMMDg6yc+fO5YVdp0+fZmJightvvHFTGigQCASCX23mZ2codbAFcyGfI50Otfz+\nWCy+JQeTngT5f/2v/8U//MM/rHotHA7zP//n/+Tw4cO+NkwgEAgElwaOY2Hb7a8dMQIGR87mkOVC\n0/cW8jne8eY9W3K+2ZMgz8zMrNu3uq+vj5mZ+psgCAQCgUDQjJ7egY4Wdf2q4GnMPjQ0xJEjR1a9\nduTIEQYGBnxtlEAgEAgElxqeRsh33nknH/vYx7jzzjsZHR3l/PnzfOlLX+JP//RPN6t9AoFAIBBc\nEngS5A984ANEIhHuv/9+HnjgAQYGBrj77ru5/fbbN6t9AoFAIBBcEniO8rntttu47bbbNjz+l3/5\nl/zlX/5lJ20SCAQCgeCSw/d139/5znf8LikQCAQCwa88vguyiFcWCAQCgcA7vgtyu2EIb0Rc1/W9\nA7JpNX2tuFzZ94pek51awd/9tpfYhNN8M34jZxM++2acTZvRkX+jXJ8CQQ3Pc8iCKuWKRdms7pNr\n6DKG1vlXmc2XmZwv4rguPfEA3fFgxzVLpsVixlssYKvkixaa5hDQvcfkraVSsVjImlRsB1WW1kUn\ntkOpbPH4SxOMz+Tp7w6xayTZVjLRSmqZujdcOcJoX5wfPdN5wIQkwY7BLsKhapLaXKa9RKq1BHWF\n51+dYXw2x5V7UoQC7aUIrUQGsvkKZdMhEdXRPEY5rsV1Xcyl9CwJ/zolxWKFTNFEkSSiYR1D7/z6\nXEgXGZvJgQRDqSjJ2PqIS68oskTIUHzt4NXiR0HCtu2Os4phdda7XzUF6/FdkH/Ve4+WbVMs28sR\nZAClsk2l4hAwlLbSVSoVi/HZAtlCZfmGND5bIJ0zGUyFCbRxM3Fcl4V0kUJ586IxXcCsOFiWScBQ\n27o5u67LYrZMrlRhKTwLy3axbBddkxsGzjeqeeS1WY6dmWdxKQg+ezHNXLrEjsEY/W2k6riui2W9\nHr0oyTIjAwl+911v4sVXp3ihzQjGvu4IvV0RKjbLsZipRIByxSGTbxxivxGaIqFpMoVS9bc/M5Fl\nNl2qZvdu62o/ik8CuxpGRtG0MReKhAMa8YjeVufJsh1Kpo21Jg60E2GuWDaZnLkqZ9isFAkGVGJh\no62korJpcX4yy3ymSK3vlS/O0x0PMtofRW+jMy4BoYCCpsj4ldggAYmIQTCgLn/OWqxrJ1Gua/OU\nV0bFtnsuCerjuyBfe+21fpfcEriuS7FsYVkOSKtPbkmScFwoFC1U1SFotDZirMXOzaVL625KAPmS\nxamxNF2xAH1doZYyYl3XJVswyeZNNsOprYfjVrNYVcUmoCst954LJZN0zsS01jfUclysclUAA4bS\ncmLRxGyeZ16ZZGx2/RZ689ky6Vdn6J8rsGc0SbjF3FnLdrAqNuU6SUy6rnLt5UPsHunikefOMLPQ\nmhthaDI7R3qQZZm1oVnlpYSiVCJAOm96SiwKGQqm5SyLcY1socILr84yMZvnwM4u+rtb75TIUjU1\na+0pajuQKVQomRbRsE64xRG467oUzWontt4p6uJdlF3XJZMvUyhaWGtOfNuFXNHCrDiEgyrhYGsd\nCNd1GZvJMj1fpGSu/j5tB6YXimTyJn1dIQZTkZYFz9BkApqC5KOYhQMqkZC+rgNbzS2WcBzHc3Si\nvdT7WPs3r9esCrPIRfaPpnnIzzzzTEuFrrvuOl8atBUxKxYl08F13aYXXe09AV1u2HPOFkym5goU\nzdZGsLom05sINrTJypWqPV1P4H5RSICmyQ1t7Ipls5Apt/zZZan6+Q1tYxu7ZFo88dIkZ8YzlFuI\nhQwZKsO9EXYNJzbs5dfs6Ypl05Ir7bqcm1jkx8+exa7TwaqxfTBJNBxYHhE3QlMkXGC+iY0d0Ks3\n4rXCUQ9dlRnujXDVnhQBY+NzVAaQaLljFzQUEpGNbWzXdalYDmXTXifuG9GKMBdKFXIFc7kj07Sd\nutLUxl7IlhibzrXsUsTDOkO9ERLRja9PWZYIG0p12sSnUbGmSCSiBkaL00ZrR7v1qNnTrY6qqzXd\njmzsTvOQvfDLzk5ulIfcVJBvuummVf9/cXER27aJRCLkcjkURSGRSPDYY4/509othL1kT9tOcyFe\ni+u6KLJE0Fg9YrQdZ+lCr7Rly0WCKoM94VU3k1+EPe0VRQJjjY1ds6fzpUprAreG2tyypr5+M3Fd\nl5dPzfHy6blle9oLXTGDnYNx+lbk0bqui2U7VCp2S6K5lrJp8cKJSV56bXrV6z2JEAOp2LoRcSsY\nmky5YpPJr96AX1UkDE0hX/KeIx0P6ewajrNnW3Kd+7JsT3tEkSES1IiFV49CN7KnW6WeMNfs6WLZ\n8nwtKTKEDI1YxFjVITMrVXt6Ll30fI6qskRXPMBof2zdSDW8CfZ0PGIQWmFPt0ojwW1FsDeqKUnS\ncl2vCEGu0lSQV/LlL3+Zs2fP8l//638lGo2SzWb567/+a7Zv385HP/pRP9q6JVhrT3dYDFWVCegK\ns+kS8+lSWzf5lSgyJJZCzXNL9nSHJTcNVZEIBTSKZYt0ruzL6F1Xq8I8u1jk6aNTjM3kO1oMpMoS\nfd0h9m5LYqgKFctuebTViIVMgZ8+c5ZswWTnSDeKorTVEVmJocqkC2XMikvYUClb7Ytcjf7uEAe2\nd9HXHUZZGhF3+ivpqkwsrBE01Ib2tBdqotzInvaKpkpEgjqhgMrEXJ5pD67VRgR1hb7uEAM9EQKa\nQkD3154OBVSidexpr6wU343s6U5qekEIchVPgnzjjTfyk5/8BF3Xl18rl8vceuut/OxnP+uslVuI\nbL6M4/r3CJfruixky2QL7ceL1SMSVFHfAPM3ZsX2ffQ+MZvjyZcnW7JoW6U7anD5rm5f597LpsUL\nJ2c67oStRJWr6wv86DTUMFSZ9/7azo5XTa8lFtabv8kjs4sFij6fT5l8mXQbDksjrjvQRyoRwM8l\n1LGwvs596BTbtpFl2eea3uaWhSBX8XQ3VxSF06dPr3rtzJkzv3JL4C3L8fXklCQJu86CoE5xf1Gr\ntjpkM54DLpYsX8UYwHZd3xfCua7/n79i+zCEXUPZcjbj0Wo25enqzSi5Ceeopkj4/cC6Im3OXg9+\n1/xVf9pms/C0yvoP//AP+ehHP8oHP/hBBgcHGR8f55/+6Z/4d//u321W+wQCgUAguCTwJMgf/ehH\n2bNnDw8++CCvvvoqvb29fOYzn1m38EsgEAgEAoE3PD+HfOONN3LjjTe2/R/85Cc/yY9//OPl0fX+\n/fsBOHfuHB//+MdZWFggFotxzz33sHv3bl+PfepTn2LXrl1tt10gEAgEgs3C0xyyaZr8n//zf7jt\ntts4dOgQAI8++ihf/epXW67xrne9i/vuu4+hoaFVr99999389m//NocPH+aP/uiP+PM//3Pfj338\n4x/38nEFAoFAIPiF4UmQP/3pT/Pyyy/zqU99ankRwO7du7n//vtbrnHttdfS19e3atJ/fn6eo0eP\n8r73vQ+Ad77znUxOTnLhwoVNOSYQCASCrcP87Ayz05O/kH/mZ2dIp9MsLi7U/cdx/F+A2yqeLOvD\nhw/z8MMPE4lEkJe2MhwYGGBycrKjRkxMTJBKpZZr1uqOj48TiUR8PzYyMtJRewUCgUDgH45j4dj+\nPha6EYGAwYtnc8jy+u11C/kc73jLnl/aI1GeBFlRlFUCB5DJZIjFYr42Chovm9+MYyvR9c43cFiL\nrPj/qMJmbOwuLe1b7Ceb085NeEhnk6JDJT9jjGpswuPnfm5eUUNe2ufd15qb0c43SEjC2vuvH2zG\nY6uqx+fZR7dtJ55I+N4Or2QzAbq7oySTGz8rvJl4EuS3ve1tfPKTn+Qv/uIvgOoD5Z/97Ge59dZb\nO2rEwMAAMzMzOI6zfMJNTk4yODhIOBz2/VgzTNNG8XmDBGcTttKqbhbvb83NeHxwUzJ5N6Ohm/Ts\n5KaU3QRXzXVc34W+mm/tr9htxvm0GTU3g82wUzcjTtGybE+iXCiWUdTNiYn1Qj5fYm4ui21vXjJx\nT49PG4P8t//238hms1x//fVks1kOHjzI3Nwcf/qnf9pRA7u6ujhw4ADf/va3AXj44Yfp7+9nZGRk\nU44JBAKBYGvhbpV/3M39pxGets6sMT8/z8WLFxkcHKSnp8fT395999088sgjzM3NkUgkCIfDHD58\nmDNnzvCJT3yChYUFotEo99xzD3v27AHYlGONWEgXfR8hz8wXKPi8s1TYUNA63M/2F0Gx7O82jwCn\nLy7y1CvtZRBvRCKi86Zd3s7nZpTKFs+dmPbVtnVdF9OsHwfZCR++dbdnq7EZsbCG3yPk2YXO95te\nSzpbIuPz1rY3XNHfMP2pHZIRnUjY8LXmVhgh/yK3zmzEL2JbTd/2sv793/99vvKVr6x7/SMf+Qh/\n//d/317rtiBCkP1FCLIQZD8RgiwEebP4ZQuyJ8v66NGjdV8/fvy4txZtcQK64uvEn207qIqE3+u6\n8qVKNZHKJ2zbYXIuR6Ho343JdV0sy/F1r2DHqcYjGqrs261elau5w2XTe4xhI9LZApZVwa8MEIlq\nEISsSKtiKDsloCucn8z6+jtlciWOnZ7FsvwTz4XFDEePn8Kq+CieS+luqo8XaFBXyBUq2D7O+VbX\nBrrLyUx+UJuT9rvmpiy6vARoaeb6s5/9LACVSmX532tcuHChpYVSbySCQR29gyzkGtVA9modWZGJ\nhKoxhBXL7WjRreM45EsWrguZgkVXVCcc0NpeJeu6Lou5Mi+enCFftpGAy7YnGe6NtD9icl1My2Yu\nXV5OOjJ0GUPrbLFEOlviZy+Oc2E6D0AspGHoSkcj8PBypqzEyQtpeuIG/V3hjlYdF0smT714nhdf\nrT4S2NsdZXSwG8dtX0QNTaZs2sxmqqlEqlJteztZyDUCuoJp2kzNF/j+0+fp7w7ytqtHSMbaH9lV\nLJujp6b58TNncV3o7QrygZv3M5SKtr2S3TQrPPPCcf6/f/wBlm2TiIX58PvezsjwAO2OwCUgVzQ5\nM5HFdav/PxnVkSTafspCUSQSYYNUMoiDxPhsge6oQTCgdiRShqaQjBnLaVydxiWuzESuLXr1I4LR\ntp2lmkKQ26Ely/oTn/gEAN/97nd573vfu+pYT08Pv/mbv8m2bds2p4W/ZMyKTdm0cdzWhdl1XWzb\npWRadZN+2g5rX+rJ14vyU2SJnriBoSmebnqlssVrFxY4vyRwKwloClft7aErFvB0M7Fth2zBJFOo\nLxThNkLVzYrNK2fmeOpofZu6O1a18bzEHAZ0eSlTdn1QuyTBtr4osbDuqfPkOg6vnZ/l+0+8Wve3\n37u9j0Q84um315ZGbnOZct3jAV1GQvJk46qqhAzMLpbqfr5D+1NctTuFrnvoQLku4zNZvvvoSXJ1\n7N/rLx/g5mu3Ew62Hsnoui5nz0/wxfseZnxqbt3xg5fv4fab/xXRaKT1dlK1VM9NZSiU1iuvoUlE\nQ7rn6zMW0uiJBwmF1n8+XZXoihnoqrfrU1UkoiGNSGi9Tb1SVL1en1BfeNutufJplnYQlnUVT3PI\n9957L7/7u7/rS6PeSLhLQmhZTtOLybYdTMvGbDJic123KvYVp+n8oixBuWK3lAEbCSjEIkbTnOSq\nPZ3npVPzS4+mbMxgT5i9owlCAa3h+1zXpViymMuWmzr+iiwRDqhNv0/XdRmbzvHDZy9QbiI4miaR\nCBlN51YVGUIBraUg9YAus70/1tJc/dxCjsOPn2B2sdjwfbqmcGDXIJqm0eyeb6gy6UIZs9L8Mg0H\nVEzLpmI1fm9AV8jkyk0FXFNlbr9+lJG+aNObcy5f5tHnz/HKmfWiuRJVkfnAzXs5sLOn6bzlYjrL\n937wJD/62QsN3yfLMu97101cdWAPitr4HMV1mVksMjnf+DcCiIY0DE1uKswBvTp67YoFm35PsZBK\nLKw3FS8JCAVVktHmnWHbdpCk5s8oexkBt/pex3Fauo6aIQS5iidBfuyxxxgcHGTnzp3Lr50+fZqJ\niYmOAifeKNgNbOyaPV0q295GVLVR7wY29kp7ulUkoCumEzLW29iu65LOlXnp1BxZD4tYJAku397F\nUG94/Y3UdalYDnOZMqbHOe2AriyNUteTzpV54qVxzk3mPNWMhfWqvVunU1QbnXu1D1OJAH1dobp/\nVyqbPPPyRZ4/Pu6pZn9PjG1DPVTq6GK1/TaZvLe5UlWRMDSlro0d0GVM02EhV3+kvRFDPWHeevVQ\n3QVKlm1z7PQsP3zqTNOO3UoGusO8/+Z9DPRE1nXKKhWLn794gi997ftUKq3b8V2JGB9+/60MDfSx\n1saWgHyxwpmJjKcFdss2NqzrPKmyRDxi0JMMLlvJLdWUoCdmEDDq29iGKlftaY/TOxsJc7ujXthY\ncGs1Jckfe1oIchVPgvzOd76Tf/iHf6Cvr2/5tampKf7gD/6Aw4cPd9bKNxBmxaJkOsubUzSyp1tl\nnY3tVmuaTUY7jdAUia64gbFkk5VMi9MX05ydzLZdM2goHNyTIhE1kCQJx3HI5CsdrVCVgHBQXb6R\nVCo2x87O8+TLkx3NtXfHDFzAsl0MTcbQ69vTLbdTgu19UaJLNrbrOpy+MM/hx09itTnpKEmwZ1sf\nyXiEiu2iKdXFZfMb2NOtEtCrAlEybVRFQpYkZheLHX2f1x3o44pdPUsdKJeJmRwPPnqSdN5su+Zb\nrhzmrQdHCId0XNfl/MUpvvy1w5wbm2675rVX7uPWX7uOSKRqY1uWzYXpHLliB3PtWnUNSO36jIY0\nehJBT/b7WnRVpjtmVBfnSRKKLBEL17enW2Wt+Poxgq1f0/V1ZbYQ5CqeBPmaa67hueeea/n1X0TR\ncAAAIABJREFUX2Vc16VQqpAvVnx7pMd1XUqmTa5YacmebpVIUKVYqvDS6XnfdiQa7g2zYzDOYs70\nbUG6pkjMZ8v88OnzlHx6rEXXZLqiBoosI/u01DlkyIQMhX/5+Wmm5ryN3jciqKvs2z2EablNpzu8\noKsS+VKFQsm/7/NtBwc5dXGel16b8aWmpsq8680jvPbaGQ4/8qwvNRVF5sPvvY1UX39L9nSrJCI6\n/V0huhPN7emWa4Y1+nvCntdqNKJVG/uXXbOGEOQqnr7ZoaEhjhw5suq1I0eOMDAw0F7L3sBIkoSu\ndba6t35NmZKPYgyQK1ocO7vg6/aAF6fzzKdLvm4LWbFdfn5syjcxBjArDqGA5psYAxTKDk+/dME3\nMQYomhbFoumrGAPYjuubGEP1+/zpc+d9E2OAiuXwzcPP+ibGUBWPp4+c9FWMAUzLoSdZf+qiXfJl\nm0TE8LWmosi+b9na6TyxoDmeJinuvPNOPvaxj3HnnXcyOjrK+fPn+dKXvtTx1pkCgUAgEFzqeBLk\nD3zgA0QiEe6//34eeOABBgYGuPvuu7n99ts3q30CgUAgEFwSeN6l4bbbbuO2227bjLYIBAKBQHDJ\n0lSQv/GNb/ChD30IgK997Wsbvu+3fuu3/GuVQCAQCASXGE0F+eGHH14W5O9973t13yNJkhBkgUAg\nEAg6oKkgf+ELX1j+93pJTwKBQCAQCDqns53+BQKBQCDokPnZGUpFfx9Ra4dCPkc6HfK1ZiwWb/nZ\n7aaCvH///paejzt27FhL/0GBQCAQCFbiOBa27W8edTsYAYMjZ3PIcsGXeoV8jne8eU/LG400FeSH\nHnpo+d+feOIJvvvd7/LHf/zHDA0NMTY2xhe/+EXe8573tN9igUAgEFzS9PQObImdun7ZNBXklUES\n/+E//Afuu+8+urq6gOro+eqrr+Z3fud3+L3f+73Na6VAIBAIBL/ieNoLbWFhoa59vbCw4FuDBAKB\nQCC4FPEkyLfffjv//t//ex555BFOnDjBT3/6U/7jf/yPl+RGIXPpAp974EXu+/4JFj3G2W2E7TiU\nyjbhoOolw7whkgQ9cYPrLusjHm6SFdsisiRx5a5u+rtDGJo/+9u6rks2X2bHYIy+ZNCXmlCNTZQk\n8JCO1xDXdcnlTSTFoCux8SbxXonHwpQtF1ly8ZD30pDxk0/y0N/9GaeevB/H8Wc/68XxYzz+zU9z\n4flv+TbnV8pOM37icShM+NbOQDCEGkwyNrlAxfKnpiRBUFMYm85g1svMbANVkdg5GMN1/fvd4fU8\nY79rui6+7okvWI2ntCfTNPmbv/kbHnzwQaanp+nt7eXXf/3X+djHPoZhtB8Z9kbCth3+6ZHX+JcX\nxpcj8pJRg0P7e3nbNcMobWSDuq5LuWJjVpxVWa2WZVPoIGgiFlKJhvTlTeFt22F6vsCLp+bajooc\n7Q2zazhJMKAut71UtpjNlNvezL5UrpDNmxSXQiUkIF+q8PLpeSoe85VrhAMqqWRo+XPKEuia0lFw\nRdm0WMiUmM+UcNzqDdpQYXp2gbLZXrSfrin09nRhOVBLcIyFq/m77fbKcukZXvjBFzj54s8oFquL\nU3bsvYp9b/7X9Ow41FbNcjHLqSfv5+yxJ8nlqvGdQ9v2MHrlO+kaba+mbZnMn32S6QsnyGarNbu7\newjE+nG0eHthC5LEtu17McJJSktBHfGIQW8yQjIRbjvAIR7W0FR5OX7R0GSSsQDd8fZTn4ZT4Wqn\nVq9eS36kKdm2vZRRXK3hR/xiTdxrNRyn2nloJ195I7ZK2pPf1EuP8i1+8VLn+RNT/NMjpzk9nql7\nfFtflFsODbF3W1fLNSuWQ7myIgd5La5L2bQpexAmTZHojhvoSznIaymbFqfG0pydaD0XOWQoXLUi\nB3kttu2QLXjLRbYsm2zeJF+q1A2Nl4DphQInL6RbrilJ1RudosjUiyjWVBlZwlNKl+O4LGZLLGRK\ny52GlRiajGOZjE97m7rpTyXRDaNu1KahyQQNFdtxW75BO7bNscfv55WnH2Z68uK648FQmF2X38C+\nt36UYLS7pZqu6zD20vc5deQHTE1cWHdc1w227T3I6NW/QSDW22JNl9zUcWbOvcD01MS644qi0NM7\ngBTqR1YDLdWE6sKg7t5hipX156cEpJJh+nqihIKtDx7W5iCvJRpU6UmECIdaz0WOhTS2D8aIBLUN\nryXwJqJrM4t/cTX9yUUWglzFsyA/8cQTfO9732Nubo7Pf/7zvPTSS+Tzed785je33+otzkKmxP99\n+DgvnJxpKoy6KnPZ9i7uuGE7sfDGF6njOJRMG9Nq7et3HId8yWo4CpWArphOKFD/Ql+J67pkciYv\nnZptKKKSBG/a2c1gT7j5xey6VCyHuUwZs8H35Lou+YJJrlhp+L4alu1waizN7GKp4ftSiQDRkE5l\no87NCgKajO24Dd/rui75oslCpkw6bzatGdRlcrk88+nGsYzxaIh4LELRbN7OSFBFVeSlEfnGv+nE\nqWc58pP/y6kTLzSt2TswzO6r38X2Qx9Elje+maYnT/Da09/g9IkjTa3Pru5eRi+7gYE3vRtZ2Xit\naDk3y9yZJxk/fwrLbuxWRCIRYsl+nECqYTt1I8Dojn04kkGz0ymgK6S6wvR2x1EbnM+SBF0RHRfq\ndhZXosjVUXgqGUJrMDeiyBK7h2IkY4Gm11IzMVxJqyNrLzVbHVnXalZH5e2PloUgV/EkyPfeey9f\n/OIX+c3f/E3+7u/+jp///OecPHmSu+++m/vvv7+zlm9BHMflO/9yikeeH2M23VgM1tIVNbj2sj5+\n7eqhVSeq67qYFZvyGnu6VTaysSNBhXjY8GxN2bbD5HyBl07NrZsbGuoJs3dbgqDhbe65kY1dKlfI\nFsy6o8JGSECuWOHl03PrRiuhgEJvMlR3RNyIRja2Wana03PpkqffSZZAV5Zs7MpqG1tVZPp7u1fZ\n060SD+u4kou0ZtlHPjPHkR9+kRNHHqNQ8JbPvHPf1ey74bfoHj246nWzlOfUU/dx5pUnyWXru0Eb\nMbJ9H6NX3UFi+KpVr9tWhYVzTzF94TiZjLeaPT096LF+XHWtjS0xumM3gXD3sj3dKomIQaorQjK+\n3saOhTR0Td7YtdqAgK6QjBp01bGxh3rCDPS8bk+3SiOxbWfUC43Ftv2arhDkOmyqIL/jHe/gb//2\nb9m+fTvXXXcdzzzzDJZlceONN/LUU0911vItxouvzfCtn5zitbHW7dJ6bO+Pcuu1I+weSWDZ1VGx\n1wt9Ha5LybQwLRd1yZ42NrCnW6VUtjg9tsjZyRwBQ+HgnhTJDezpVqna2CaZgoVlV+3pQrFCJx9f\nAibn8rw2lkGSqjc6VVOwOyiqqzKS5FKuuEv2dJGFbNlzp2ElhiZjWSaTSzZ2fyqJpumehWN1TYVg\nQMFxqlby8Se+zitPPVTXSm6VUDjC7jfdxN63fhQjFGfs6A84/cIPmBw/1347AwFG91zD6NUfxIh0\nk5s+yczZ55meGm+7pqqq9KT6kcP9oATo6u4lNTBKsdL+3KgkQW8yTG93jFBQb2pPt0o0pNGTCBIO\n6kSDGjsGo0RCesfXElSF0stItxErhdnfmt5tbCHIVTx11zKZDKOjo8Dr9pnjOL7MIWwl/u8/H+On\nz41R8mEl5dnJLPcePsH7b97F9v4YvkzYSxIBQyMagpChIXXQM60RMFQu29HNaH+MgKGg+vCbKopM\nImJgWjZnx4st2dPNcIG+7jDRsE46Z1Kx3Y7EGFhul+Q6XJzOkWnBnm5GdY5aZWSwOq9aqrjYHYhx\ntaZNuWIT1Fx+9JW7OH3i+Y7bWcjnePGph5m68AqhWC+TF09hN7GSm7azVOLVlx5nfuIUvduuYn5+\nBstqb9FbDcuymJy4SDSaZv/178OI9VOsdPa7uy5MzefJ5Epcc2CIUEDtvLMMZAsViiWLG68aYPdI\nsqE13io10awt2upkkVYNWa7WtKzqKNzPmrbt+FLvUsPTN3bFFVfw9a9/fdVr3/nOdzh48OAGf/HG\n5PxU1hcxrlGq2MiS5I8Yr0BXFV/EuIYkSURCui9ivKIoZdPxRYxXl5Vamiv2Qr5s+SLGKylVGs9T\nt0MmX2J2qv0RbD2mxs+TW5zqWIxXMjc7hVnKdCzGK8lms4TCEV+Es0bRtNFVua0ppI2wHJdY2PBF\njGtIkoTrdrYKu15NSXJ9Fc9qO8Va4XbwNEL+7//9v/OHf/iHfPOb36RQKPAHf/AHjI2N8eUvf3mz\n2icQCAQCwSWBJ0Hevn07Dz30ED/5yU8YGxtjcHCQm2++mVDI33QMgUAgEAguNVoWZNu2ef/73883\nv/lN7rjjjs1sk0AgEAgElxwtTxwoikKxWKRS+eVHZAkEAoFA8KuGp5n8//Sf/hN33303Z8+exTTN\nVf8IBAKBQCBoH09zyJ/4xCcAePDBB5cfe3Ld6i4tx44d8791AoFAIBBcIngS5B/96EdA9dnjhYUF\nksmkr0vwBQKBQCC4VPEkyPF4nE9+8pM8+OCDWJaFqqq8+93v5q677tqs9gkEAoFAcEngaXh71113\nsbi4yNe//nWefvppvv71r5NOp/mLv/iLzWqfQCAQCASXBJ5GyE888QSPPPLI8nPH+/fv5zOf+Qy3\n3HLLpjROIBAIBL/6zM/OUCoWf9nN6BjDCKzaPbGQ9xb44kmQ+/v7WVhYWLURyOLiIv39/Z7+owKB\nQCAQ1HAcC9t+Yz9SWyzkuW7fLuLx1SEZsVjroRmeBPm9730vf/RHf8S/+Tf/hoGBASYmJrj33nt5\n//vfz2OPPbb8vptuuslL2S3HjsEYZyYyHaX9rMTQFNK5MsO9kY6SVFbiui4Tczn6uyPo2tYN93Bd\nl0KpguM4Pi8AdNFVqeU86VYIGyrxSDW0wi8USmA5IPu3m10sEiI1sJNsesG3PYP7BkcJRFPkcnls\n25+9p3tS/ahGBE0zfdu/oKurC02VcZF92x89EtRQFRlFkToOKqmhKTKW7fh63ldzh/E1uMF1XVzX\n/5pe73M9vQNv+LSnXDZNPB5flezkFU/xi7feemvzgpK0vBr7jcwrp+f4xk9e4+SFxY7qpJJBhrrD\nRMI6kYDK7tEkoYC3fOG1pLNlHnn+AsfPLZJKGHzolj2M9EV9E3u/yObK/PjZs/z42fNoqsxNB0dJ\nJcMdhWxIwFymyNhMAajmTkuy1FHYQDV+kaWMapd0tsRCtkyh1L4w6YrL/PirHHn6B7iuwxWHbqV3\ndD9lu/3OU0BXCOpKNb7SdTnx9Lc4+sR3O4pKjERijOz/V/Rf+RtoRpj0+aeZOP5IRzWDwSCDO64k\nufsW9GAMKztOduok09MTbdfUNY09+y/nure+h3hXily+yNRcltnF9m1OWYIdQ0luuGqY3q4IhYLJ\nbLpIptBZ56GvK8h1B/oZSkV8iTWs1ajlIvsVlbjZkY5e+FWIX6wXtVgP3/KQLzUcx+Whn53hxz+/\nwMxiydPfxsI6/V0hUsn1YeXDqTCDqQiq6u3mXKnYvHRqjh89e561v9r1B3q55ZoR4lHDU83NwLJs\njp6a4asPv4K5JjVrMBXh0P5BAh47JbIEhZLFqfEMzppYHk2VSIQNTI+irMigqQolc70TYlYsFjNl\n5jJFbA8DMUUCqzjLkSceJpeZX3XMCEW55oZfx4j24WVwJ0kQC+mAC9LqG10xn+bID77AiSP/Qi6X\n9VBTYtvuKxm66n1EeveuOmZVSsy88hBjr/2cbMZbh3Ro215Su99KqGfXqtcdx8acO8Hi9FnSaW8Z\n4yOj2zh4/S3s3H/1qtdd12V2IcvMfJ5swZur0ZsMcfX+fi7f1bvq+nRdl/lMkYVMue550YhoSOOy\n7UkO7u1dd83XYhO9jparolk/X3iloHqtWRN3v2p26gQIQa4iBLkFMvkyX/3n4zx/cqbpRWpoMqlk\nkMGexlayLEvsG0mQiAVa6pFenMry3cdOk23Qe1cViQ/+2i7etLsbzaPY+4HruozPZPnHHx7n7Hjj\nm+41+/vZOZREauEidhyHi9N50k2iESNBlaChtmRjBzSZiuPQLG0wXzBZyJZYbMHG1ihx5thTnD15\npOH7hrcfYPcVN2C1YGNHgiqaomA3sQGnzrzAkZ9+hdeOPd/Uxu7tH2H4wC307Hs7krTx919YuMDU\n0X/mwumXm8YydvX00r/jEPHtNyDJG597tpmlMPUKM5PnqVQaOxCJRIIDV17L1Te8C1XduANXNitM\nz2WZWchTadLTCQdU9m3v5saD2xpenxXLZmahQCZnYjXJZdQUiW39Md5yZT+hgN7wvY3EcCVeRqyb\nUbPVke7ro3cJuYMoWCHIVYQge+Dl12b45k9P8erF+mKTSgQY7AkTDbc+So2GNXYPJQhuMGLM5Mo8\ndmSMl0/P1z1ej76uIB+6eTdDPs5ZNyNXMHnk5+f4/lNnW/4bXVN468ERuhP1bWxZgrl0iYszeU9t\naWRjV+1pl7KHcHvHqdrY89lS3XUFuuKyMHWKF544jOu0NqqSJJkrrr+N1PA+ytb638hYsqcdl5Z/\nQ8exOfHENzj61INMTZxfdzwcjjCy93r6D34IIxhrqabruiyefYKJE//C1MSFdccDgSCDOy6na/ct\n6KHW584qmYtkp19lZnpy3TFN09iz9zKu/bV3k+xufcFoNle1sefS621sSYIdgwnecuUI/T2Rlmvm\niyazi8UNO8J9ySCHLutjpG/jm+xaHMfFdTcWxnZGqc3Eth0rubWa9UfvXhGCXEUIskccx+U7j57i\np8+NMZeu2tixkEZfd4jeZKhtARzpjTDQE0FVqxdMxbI5dnqe7z99HqfNn+gtV/Rz89VDnjoIXrEs\nm1fOzvLVh45S9mjx1RjujXLN/gEMo9opkSQolS1OjWWw20yN11SZRFhftrFlqdoB8GpDrqRsWixm\ny8ylizhutaZTnOPFpw6TWZxtq2Y4kuCqt9yBFklhO9U58lhYx5VcJG/bBCxTyC7wwg//lpNHHiO/\n9NjFtt1XMHzV+4j07W+rpmUWmX7lIcZee5ZcNgPA4OhuenffRCi1t8lf18exLcy5E8xPnSGbrdrt\nw8OjHLz+ZnYdONReTadmY+fIFasimkoEObivnyv29LV1fbquy3y6yEL2dRs7ElTZv72La/att6db\nZa2N3epIt3HN1WLe7pzuZtdcixDkKkKQ22QhW+IrDx1jYjbPYCqMrnlasF4XRZbYM5KgULZ46LEz\nLDaxaFtBU2V+4227uHxXN6qPFxDA+HSWB358nFMXO1v4VuPQZQOM9ieYmM378tmhOq8XWBppdrLw\nq4bruhSKJmOTM5w9/iynjz/nQythZNeb2HvVWwkGIzhtrFKtx8Tp5zjyyP1E+/bSu+8dLU0PNKM4\nf5bxo98nnOwnvu1GZKXz894qZSjPnWR4eIRDN92BqjW2fVuhVKowu5gllQhy09XbMPTO21mxbGYX\nisQjOjdeOUAo2Hk74XXB63RB1WbXrAlxp/Z0PYQgVxGC3AHzmRJf/9GrvtY0KzYvvDqDWfHnkY4a\n/8+d1/tyU1rJPV96nMl5b3ZyMw7uG6Tk82fvTQYp+1zzse8/wMsvv+hrzbe/+3cIJIZ9rVkq5Lg4\n5U+HqUZQc1hMt76ArBUO7BlldGTQ15qpZJB9o+0/glKPkKFy9b6UrzWBZWvYT/x8lKmG/48vVhGC\nXEUkQwgEAoFAsAUQgiwQCAQCwRZACLJAIBAIBFsAIcgCgUAgEGwBhCALBAKBQLAFEIIsEAgEAsEW\nQAiyQCAQCARbACHIAoFAIBBsAYQgCwQCgUCwBRCCLBAIBALBFkAIskAgEAgEWwB/Nze+hHAcl1MX\nF4kEVXLFxrmuXggaCruH4hw7t4Bfu4xfuz9FOm/Soyq+7Zc7Np1l50gXc5li0wzaVgkHdeYyJQKa\nguJTnrOhyThtJkZthAxccegm5hcXGb+4PuawHSKxLoq2ju5YyLI/l6VZLjM7PY6Cgo0/iV/hgMaH\nbjvA8dPjPPrsa77U1DWV664YwTCCnJ/K+VJTVSSuP9BLNKh7ju/cCAno7w76vkd0LeWp+l/wq6bt\ne/RqLbDC9Sn8ZCXzszOUiutjM39ZGEYAyeO9spDv/NwV4RJtcH4ywytn5ljIVhOJFFmiUKxQ7kCY\nZAk0RV5Rw+XseKajm0l/d5Cbrx4hEQsA1SD1SEgnElTbvqCyBZMT5xaYWSxWk19wuTC5yNHT7cUP\nQjU9pjsRpmJXE5nCAZVwUEPXlLbbKQHJmIEEWE419UqW6DhkIqApWI6DZbvIOFw8e5KHvvsAVqW9\ndCpJVjhwzS1Ee7ZRtsDQFKJhA0XV2s6ZdR2H9PwEszPTZHJFNFUhGotRIYjUpthLwB037eUtV40S\nMDRc1+XC+Dxf/e6TTM62HzRx8/V7ufHQHoKBaoehVKpw4sIC2UL7ndyrdnfzljf1E48GcF2XfLHC\nmYkMmXz9TONW6IoZjPZFCC8lPLWTWbyWtbnIm1HTj8zitbnI1Xb6k4Nc4zOf/yeCobBv9TqhWMhz\ny7W7iMe9h13EYvGm4Rsi7ckncgWT505MMzmXx15zX6/pRiZn4vUL1VUZ23HW1wRKpsUrZ+bJl1q/\nQamKzO3XDTM6EK8raAFdIR7RMbTWLyjbcTh5fpHxmVxdUatULI6emmbKY/pTIhZCVVSKdXKKExGd\ngKGieRwtx8M6uqZg1ukgBTQZ23bwqsu6IiPJ9QXdqRR4/pmf8cyTj3qqObzzckb3HqJoaeuORUM6\nwaCBonjrPBVzi8xOjzMztz7hKRoOogfCmAQ91dy/vYf33XwZqa4wa0dxlYrFc6+c52sPPYu19gRu\nwMhgkg+8/Rr6eurd9FzmMyWOn1v05G50xwze9eZtDKYi65wg23ZYyJR4bTyD7SGGU1Nldg/HSUSM\ndTXXil+r1ASuXozhWvHzwkZ5yp3WhPWdhEafoR22UtpTq6lN7SIEuUMcx+XlU7OcHkvXFY6VKLJE\nxbJbsrE1RUaSqCsca2vOLhZ55ex8Uxv76r0pDu5NNY1alCUIBTQSUR25yUU6PpPjzHiGdJOMYlmC\nhUyRZ18Zb3pzDgU0wqEghXLj71NTJeJhHU1TUJv0yHVNJh7WMa3GX5Isga4py2HzjZAAQ2/tvbnF\naX7w0LeYmhxr+L5wJMllh24FI7GuE7aWZCyArusoTXKHTbPM4swY0zOzmJXG514yHgU1jC01zvMN\nGiq/9+sH2bOtu2mvfzGT55//5WWeeOFMw/dpqsK/vuNa9u3oR27ye9q2w4WpbFOXSJElbrtumMu2\ndzU978umxcRsgbHZ5h3Hbf0R+pIhtCYdVy8jRtu2AanpKHgjcd2oZlUYG7+3lmfcygi81dF6u52S\ntQhBriIEuQlj01lePjXHfLbs6e8UWSJfrNQVWxlQVbmpEK/DdTkzkWZsprDuUG8ywM2HRuiKBT2V\n1BSJaEgnXMfGzhcrHD83z8xCEW/TsC7nxxc5dna9jS0B3cnIsj3dKuHgko2t1rexu2IGSJLn0U8j\nGzugydiOS8VDTRmb86dP8PD3voFlrbZIJUlm/zVvI57aSdmDI2voCrFQAFnV6o5UMkv2dDq7/rzY\nsKamEo5GMd0g8hqxl4B33rCHGw6OEgw0Fu21bTk3Nsvff/tJ5hbWC95br93D267bR8BDTYBiqcKJ\n8wt1O7lX7OrihisGSEQDntqZK5icGc+SLa63sZNRnW39McLB9c5Fo5rVEWN9EW1XuBoJY7sj382q\n2YnVLgS5ihDkDSiUTJ47PsP4bK7pKGYjZAlcVtvYuiphO27bNSWgVLZ4+fQsRdNBVSTefu0I2wbi\nHVlHwSUbW9cUHMfl1QsLjM3kKJntz7lWKhWOnJhiLlNdrJGIhlDV+vZ0qyQiOiFDXV70FQtpGLrq\nvXOzgrXCqylVG66T+WbbzPPcU4/y82ceB2Bo+2WM7DlE2W1/cVVsycaWl2zsQj7N/PQ407MLbdes\n2tgRTAJIksSekS7ef+sB+rojtLvIyDQr/PzoOf7xn5/DdhwG+5L8xu1X05+Kt10TXOYWS5w4v4jj\nuiQiOne8ZRvDvdG2z3trycY+NZbBdlw0Zcmejq63p1tlrfD6Ye3WE0kvI+hWa3oZQW9EtV3eP6sQ\n5CpCkOtw/MwcJ84vUvAyjGmAIksUyxa241BpYqe2iiyB48Lu4QQBw59VubJUvaAuTuea2tNeao5N\nZ5icK5JvYk+3iqbKJKMGQ6mIp9FrI2QJVBkkRcY0Hc/rAOohAYtzE7x6bhpJT+DHYnRJgng4QGZ+\ngvn5OUqmP+doMhHld973a7xpz6BvK4gXFvOcn5hndKjHtwVAluUQj+js354k0MSebpWSaZHJmyQi\nBrqHdRWNqI0YHcdpWzTr1ax28Ztb3q1SW/Tlb82q2Ktq6/WEIFcRjz3V4cJU1jcxBrAdF1WWKJn+\n9X0cF3YMRH0T41rN2cWib2JcqylJsm9iDFCxHGRJ8k2ModrOig1uu9ZFHVzAiPaAXsHy6dEr14X5\nTIHs4oJvYgywsJhl77aUr4/zJBNhDEP37bNDdapn93DcNzEGCOgqqiyh+vSoHbw+yvRLjGs1Lcv2\nJHTNkGUZ27Z9/d1lubq6W+AdsTGIQCAQCARbACHIAoFAIBBsAYQgCwQCgUCwBRCCLBAIBALBFkAI\nskAgEAgEWwAhyAKBQCAQbAGEIAsEAoFAsAUQgiwQCAQCwRZACLJAIBAIBFsAIcgCgUAgEGwBhCAL\nBAKBQLAFEIJcB133b0/blTU7j/FeTScJRxuhqTI+bpVbrakpGD5t2l/DdavpPH6iKqD7/OGDuuop\nxq8VQoaKrvtbM2joFErrowg7RVX8Puur+JmJ47rucjKTnzVX/q9fNSXJ35o1HB/3Gwc6yka+lNlS\n4RK33norhmFgGAaSJPFv/+2/5Y477uDcuXN8/OMfZ2FhgVgsxj333MPu3bsBPB371KfGys/2AAAg\nAElEQVQ+xa5du5q24+DeXmLhNOcnOw+ZCAdUdg8n2L89yfGz87x0ao7FXGfhDboqo6symbyJ60Iy\naiB1uIm9LFXFeKQ/RjRsMDaTJZPv7AatKBKOXQ1uH+6LsJgtMZf2liu9FkNT6E0GGUyFUWQJ3ZEp\nlKyO0pkUGYKGiiSB5IKuVWt2co+SJYiGdEIBhZ74do6dmeHCZLqjTpQsQXc8RDQSZKg/ycTFc0xM\nTlMst38+SRJ0JxMogQT/7zee5zdu2ce+7T0dhw0ENJneriDRkMHZiTQzC6WOQyZCusJQb4RISMe2\nbfxIKFqZDexvzep57zi1OEL/ar7+753VrAVA1Npp2/7U7DTC8VJmS8Uvvv3tb+dzn/sc+/btW/X6\nRz7yET74wQ/ygQ98gMOHD/OFL3yBBx54oKNjjcgspR2VzQrHzi4wOV/wFHwP1ZHBUCrCNftSBIzX\nRzMVy+HxF8c4PZ7B9Ji3K0sQ0BUkWUJZc4GnEgFPYfIr0VUJTVVWXUSu6zI2nWV6oUipjfxiVZFY\nzJWxVvxpLRh+PlMiW/Au9r3JIIPdYSLh1z+n67rgVt2CdnKWQ4aCqqy/YTqOS6XNmuGASiSgYRir\nXYGpuSwnz80xOZf3XDMeMUhEQwQC+qrRRzabZvziBSamZr3XjIYIhhO4WnRVzeHeKO992x76uyJV\nxfaAIkskowb93aFVNQvFCqfHM9VOpMd2qrJEKhlg+5rM73qZvq2ykXB0kl+8Ngt5Je3mF9eiDBXF\nv5qNvreVHRSvNWsuQzujYxG/WGVLCfKtt97K5z73Ofbv37/82vz8PO94xzt4+umnl0+8m266ifvu\nu49wONzWsZGRkYbtyKyJH5xbLHDi/AIL2dZGIj1xgyt2p+jvDm/4nqn5PE8fnWR8ttBSzYBeXzhW\noioSvclQyzFyqiyhqTJaAzu5bFqcn8wynynSSjKhqkgUyzb50sbOQsWySefKLKRLlFsYMcbCOgNd\nIXqSwQ0v9tpNpmTaLcUyGpqMoclI0sY381rNcsVpaWRraDLhoEY4oG5Y03FcXj0/y9nxxXXnWT2C\nukIiVh0Vb/Tbu67L7PQE4+PjLKRzTWsGDI1YLIGrx1GUjU2yt149wg1XDhMKttbRiwRVhlJhdG3j\nmjMLBS5M5yi2GMcZj+jsHIgRamD7exGRVkW8kbhuVLOZiHupCa0JrtdOSSvfldeatUzlTjKv//pv\nv0coHGn77xthGAEkD52rQj7HO968R+QhA3z84x/HdV2uvPJK/st/+S9MTEyQSqVWnZQDAwOMj48T\niUTaOtZMkNfSnQjxlniQ1y4ucmEyu+GoKRRQ2T0U58DO7qYncl9XmPfctJOXT89y9NQc6Q3sYV2V\nMZbmtJvVtGyX8dk8sZBGIhrYcHRTs6d1TWla09BV9owmmU8HGJ/JkdlgZKvIEo7jMtuCJa2pCj2J\nEJGgxkKmzFymVP+/rcn0JkMM9ISbBsdLkoSiSIQMsGzIbzDVsGxP03xkUatpSNXfIV+2qNd9lSWI\nBDUiQbVpZ0iWJfZtTzHcF+f4mWkuTGep1HFKZAm64iFi0SC61ni+WJIkUn2DxJM9VRt7appSuf7v\n1J2MowaTSGqgYU2AR5+/wFMvj/OhW/exZ7R7w5u4ocn0JoIkYs1rppIhuuNBTo+lmU2XsDewsYO6\nwmAq3LBTW6PWrmZ2qRfhqAqr1NTGXmkle6nZyMb20sGonaNV8XY3rOnFSl5Zs5E17qc97TgWtu3/\nGoZiIc91+3YRj3sbfcdiv5zR+pYS5HvvvZf+/n5s2+Z//+//zZ//+Z/zJ3/yJ+sWMTQa1Ld7rBmS\nJLFnJMlIb4RjZxeYns9TGzSpssRgKsw1+3oJBlpfbCNJElfsSrFvtIvHXxznzHhmeSS2bE83GMFt\nRKZQIVuo0JMIrmtPPXu6Fbri1Rvu2FSW6YUC5RUioioS6ZzZ0sh0JQFDo79HJRxUmc+UyRVfvyBT\niQCDPWGiYcNTTUmWUSWXmKJiWu4qu71qT8uerUhFlkGGqKxSsd1Vo7tQQCES1Ajo3i6lcFDn0IFh\nhvtynDg7y9T86zZ2PGyQiAYJBA1Pv72u62zbuYeu7hTjYxeYmJ57vWYkRCAaBzXmqaZZsbnv8Cts\nG4jxnrfupbcrBEvLExUZElGDge6wp5qyLLF7JEF/j8nZ8cyqzqgiS6QSAXYMxj3/TrIs47outu2s\nGt11IhyKoizXXDkCXj3a9Va3Jt5ra3Ziwdc+29pR9cqans/7DTo6Kx0BxadFez29A0Q3wbLOZdMk\nEvFNG+36zZYS5P7+fqB6wn7kIx/hXe96FwMDA8zMzOA4zvJJNjk5yeDgIOFwuK1jnRAwNK7e18vM\nQoHXLqZRZHjTrp6WevIboWsKNx8a4bIdeZ4+OsVirowiy16n71bhAjOLRTS1RF9XGENT0DXvQrwS\nWZIY6Y+R6gpxcSrLYq5MybSZTXeyqEgiFgkQDGhk8ibFUoW+rhA9iY3t6VZqSpKEobnomoxZcTA0\neflYu8iyjC656KqMaTmEAxoBQ0HuoGZfd4RUMsRrF+Y5N5EmHNQJhQLr1gh4IRpPsDcWp6t7nImJ\nSXQ9gKPGkdT2L/dzExn+5h+f5dZrt/GWq4bpSYQY6A41dS4aEQnqXL6zm+mFIuOzeQxNYftAlJCH\nTu1a6olEpwuq6tesjnY7Ye216IfAbUbNtd+fn0JcIxQ0iESaOyxecZ0y3d1RksmNbeKtxJYR5GKx\niGVZRKPVL+573/seBw4coKuri8svv5xvf/vbfPCDH+Thhx+mv79/2XY+cOBAW8c6JZUM0ZsMEQlp\nvi3x7+sKc9t1I3z30dN4HGxuSMVyuTid48D2LmSfVj4GdJXdI0kefWGsrcVZ9dBUhe54kNS2JBWf\nHueSJAkJiIWqo2W/agL0JQI4Pj3IJssye7f1EI8EmV6sb997pWpjDxEIxRmbyfn2fOOPnz3HjqE4\nh/b3+VJPkqRqByxudDQHWY+VnXG/aHfRUjNqo1h/a/r/+TejJkChWEZR/Tn3V5LPl5iby2LbW0bq\n6Ol5A8whz87O8p//839enucZGRnh05/+NAD/43/8Dz7xiU/w+c9/nmg0yj333LP8d+0e84N27OSW\na/q91m4TbiKb8aSh3zclqInoJjxn6fNPtDmffRMeP9mEZaDiuVX/2TrLdVtjM5rrUv0e3ijfxZYR\n5JGREb71rW/VPbZjxw7uv/9+X48JBAKBQLCVEE9vCwQCgUCwBRCCLBAIBALBFkAIskAgEAgEWwAh\nyAKBQCAQbAGEIAsEAoFAsAUQgiwQCAQCwRZACLJAIBAIBFsAIcgCgUAgEGwBhCALBAKBQLAFEILc\nAbLkLkel+YVZsehNBn2taWgylYrdUdrVWmzbocfndgYNpZoc5GNNy3aYz5RwfPzsruuymDNxNogO\nbAfLsjl5+iJmxb8IOlmSeNuhEbpbiEVsvSYM90Z8PZfg9QQhf2tW9172E8dxN6Gm4/v36fd3CdXf\n6I2yBeUblS2zdeYbCxdDU9BUBUliXdxbO1Qsm4VsmbJps2MoTioZ5OT5xQ2zl1tBkqA3EcIwVMqW\ng+O6aFo1grBdXNfFrNhULIfBngjdsQCnxhaZz3SS+ASX7+hiKBVBUWR6EgHOTWSY6SBowXVdSmWL\nXNGiULaIlB0iIRXDY0zi2pqu6y7HOpYqNpGgSkBXO/rtT5+b5OWT55mczZCIhuhNddPV3TxTuxEH\ntid568EhkrEAN101zONHLnLv4Vc2zB9uhWv29/GRd7+J4b7Y0g1/46zcVnk9xrAWndh5zZWRg67r\nz/W5sib4W7MawehPzVrbqhGM0rqIx61UU7AeyfW7a/YrQCa/sbhoqoReJ0/YS6j4SqqjrRKFosXa\ne6VtO8ymi7x2Me25ZxqP6MTDxrpQCVkCTZHRl7KWvVBZEmKrzk09nStz7Ow8lseYqsGeEPu2dRE0\n1gqlSzZvcvzcguf0J9OyyRcrZPKrR5uyBLGwTjigoqrekoVcx8FyIF+yVr0uAZGQRiSgonmMIlxM\n53jhlTOcvjCDtcZp6euJ09fXRzjsLdYzGtJ4z407GOmLrrthTs3l+MaPj/P00UlPNSMhnT/5rUNc\nuad33Wds97yv/e3K7N4atRFjO+lPG9WstrO9mhvlKXf22W1AWve3nWQ327a9JJR+1tzoN1qZB925\nMH/5m08R2aQ85JuuGNhSecip1MZpT0KQ61BPkBW5mlusNbmRb3QC16NYqrCYKzcVsYplc3Yiw9R8\nsWlNQ5XpSYRQ1Mb/fUWW0DUZVZGbXlC27VCx7KYRho7tMDGX58xEtnk7NYVr9qVIRtd3GtbWnF4o\ncHo807SmZTsUyxbZvEmlwXca0GQiIY1QoHl0Zm0UUzLthjV1VSYcVAkHtab5yJZtc+SVM7x6ZpJM\nfmMXIGCo9PV0kertRdMaZwRLErz92mHetLOHwLrOzevYtsOJc3P87TefZzHX2NWQJPjt2y/jnW/Z\nSSxibPi+laPHVm7OGwlHZzWbi+PqEak/NWvva/Wab1XIvIh9qzW9dHRa/f476eisRAhyFSHIdVgt\nyK/b061aNM0uEGvJni55sKNd1yVbMDlxfpFynb+TJEglggQMb+HuG434a//Nmj3txeksly1evbhY\n94YvAQd2djGcCnu6iMumxdnxNHOZct12lswle3rNCLYRkaBGJFjfxq7Z0xXL9TRtEDKU5Zr1fvsz\nF6Y4euI84zPplmsmY1UbO9lV38beN5rgbVcP0RVvfU6/UKzw6PPn+doPj9edbzy4J8VH3nMlowOx\nlkdAzYSpliXsJVO42ejOq3BXaza+Pjezphert5V2eOkMbHbNTqYahCBXEYJch5oga0p1FNlu729t\n79F1XTL5MrlCxZPAra05s1jg1Fhm2caOh3XikcYjzUbIEmiqjP7/t3fvQVKc5b/Av32f687e2Bu3\nBERJPKiBZEOJB39ZORINSDQiSRViypCIElNFxChFFX+ISlnHmNKUMbFiSLynjjka66ikhChJiqpT\nGD2Q0jUXJLsLuwvsfXfu3f2eP5qend3t6enu6dnt3Tyff5LdmX3onp73ffp9pqcfabKMnc9ryGu6\n6xJ0sdHxDP719nDhc8uW+giuu6YO4ZC7k4YCxjCWzOH1rmHkr64g8nkNExnV9mMGOwIPxCNTy9i6\nrkPTgVRG9dSjlYNROo6ERchXY46OpfCPf57D+QtXXJfgAePQtjTWoqm5CZGIUcaOhkVs2XAtlrXE\nIXhoGs8YQ/9gEv/rz//C31+/DACIhCQ8sGMdbljdXLYaVIrV6s7tJO8kZiWl2MmYU1d3pUrJcx1z\n+mvnpMpgx+q1q6QEXxzDy98//OP/g0g05vnfVZQQOIsTnVRyAh9dv4oS8nw2nsoiJIkQxfLl3HLM\ns8dcXsPoRNa27OlGNqeiu38cgsC7/jy0FJHnIAjG1anlytNO6bqO/oEkmuojqK8JeT5pKKZpOi5e\nHkNn1zDGk2ohOVciJPOIhSWEZBHZvI6ch6Q5nSzyiCgC3nz7At4634fRCe8XqZnCioTmxjrcueVG\n3PDuJtcVESuqpqPz/AD6roxj083XojZe+VXZk1dNM1SSjKxjGqoR04/PRItXjH5dqAVMJkzAn+0E\niq/w5nyP6WYh8z8f/x3CEXfXS5jSqSRuuXElEgnrFXZNTcLziUs12CVkusragiwIri/QKYXjOAgC\nh/HRtG/JGAAUWUR9IoRkxvtV2NOpOoPO4Hn1boXneaxYnIBcwdXN0wkCD1XnKrqye7pMToem55H3\n7+VETtUxMp7CmX91zbhoy6t0No/+K0NY++4mKD4kYwAQBR5r3tWEm9/bBrHMtQdOme97Xdd9mwzN\nmF5XYbMdE/DnpMFkJng/Y/J8dWKqLk9oG5taPZesJ8ZHkUgkArUK9io4pw2BMj+KBn6czc6Kamxn\nVQo71TnuVYlahZeU46rx3VXfQ6Iar+h8KRRWZzvnS8yFjxIyIYQQEgCUkAkhhJAAoIRMCCGEBAAl\nZEIIISQAKCETQgghAUAJmRBCCAkASsiEEEJIAFBCJoQQQgKAEjIhhBASAJSQCSGEkACghGzBaXs0\nN6pxm8tqxKzKTfT8vDn2VUYfZ39j8hwHvw+9yHOQfbo/tInn/b8lpdlgwO+Y1bm76/wYS9VQrXnE\n71tyzpfXM2goIVsQRQGaplv2iXVL1xk0TUd9IoSI4k/DCsCY6BcviqAxoUD0KYvIIoewLCAk8/Dr\nXvOqquHtvlFcGU5O6VZTCabrqK8J4X3vakRtTPYlZmMihA+8exHes6wOiag/MeMRCauuacAnPnID\nlrfV+xLzmsX12HvXf0dtTAEHn+5tzBgUyTjB0TTdl5jG+NHBcZzvMXme83F86oWOTH6PeWBym/2K\nyfNGww4/YjLGrrZ25Aqvg18xq7GoeSeg9os2yjUdt1OqIXk2p2J4PIO8x/aGPAcosgBZmuyelMmp\n6BtIYiKteoopChwkgZ/S4UrTdeQraUPIGEYnshgt6lPM8xyWNccQC8ueG05kcyqy+cltUjUdb3YP\noXcghUzOfaumaFjE0qY4VixOFI6xrjNcuDyOy8MpZHLu91+ReNTHFdTXhsEXxXz1tXM4+3oPhkZT\nrmMmYiHc0r4SX/jMhkLLRcYYMlnV6K/s4fVkjEHkOYQUYUb/Xq+9dkuNmUr6IZtjaXrMSvohl47p\n/5gv9W+5izn1taskJmDd+7jSmGZcL8fj6P/+vxV1e/rQmtZ50+2J+iFXyG2Dcasm5cUYYxhPZjGe\nyjtudcgBkEQeIUUsOViGxzK4MpKekrDs8JwRU5aEkjFVVUNO1aG6aB2ZyeZxZSRdsqwaC4toWxSb\nclJRjqbpSGZKn3CMTmTxVs8wLg2lHZXdRYFDS0MU71lWh5BivR3pjIqeS2MYGM04Ok48B9TGFTTU\nhhAqsW/jyQxeOd2JN9++jGy+/AmUwHO44boluG/7eqxa3mT5HE3TkM5q0K4mg3IYY+A5DiHZvs2o\nmyRaKnGUiutuLNknXbfj00ki93vMmzHdnOg4i1n+9Zn+/HLHyG3MSk6MTJSQDZSQHSp19lvM7dm1\nrjMMjaaRLrOyk0UeksRDdNDwW9cZ+geTGJnIwq4CJYscJFFwNIgYY8jlNeQ1HXaVMlXVMDiSRtbh\nqrqlPoL6mhB4m21gOkMqq0JzkBEZY7h4eRxv941hNJkv+byGmhBWLKlBU52zhugDIyn0XkliLFU6\nZiwsobFGQTymOIr5n55LOH3mP+juGyr5nGWtdbjjf6zB1v/6b47eT7m8hmxOg85sEjNjZU/sijl5\nTztJHFM3ofxKzO2K2klMo9QLxz2fqzHmgfL75mWlWq2YQOlE68eK2kQJ2UAJ2SWrAehk4NpJZ1WM\njmeQn7YK5TggJAmQZecryULMTB79Q6kZZWyR5yCJvO3KqBSjjK0hN73czhhGk1mMTuSs/9CGwHNY\n1hxHNCJh+sU62byKrIeSsarqeONqGTubnzzZiYZELGmKYcWS2kIp2alCGXsohUxRBUKReNTFFTQk\nwq6PvabrePW1/+Dsv7sxPJYu/L4mqmDjjSvxpTs3IBxy93k2YwzprGo0iC/aR8YYBJ5DeFp52vG2\nWqzu/CibzmYp1uv4rMaYtyvtT99+p0q9dtWIaayKnZ+ElUMJ2UAJ2SOzpGWo/I3JGMNYMouJq2Vs\nSeQQVqSKzzyHRzO4MppGXtXLlqedyuc1qJqOvMaQzaq4PJKq+KrfeERCW2MUkiSWLU87NTqWwZsX\nRjA0lkFzfQSrltchcvXzV69SmTx6+scxNJFFIiKjIREqWfJ2amw8hVf+9jrOdV/G9StbcO+n12P1\niuaKYhaXsXmOu3rdQeWTp5lEzeNdSZmymjHNMqoR15/E4feYN2MaVzkbPwf19TSTuhnXj5jFKCEb\nKCFXwHzp/LzEX9V0jCWzjsrTTuk6Q3f/GDgPF9SUwhjD+d5RpHxInMWuaauxLYu7xRhDKpNHNOzP\nldOmkbG0r68nALTUSrjhujZf30/ZnOrLSVgxrxfu2DGunvY3ZjW2sxpjHkBhFepvzPnxmgKUkE2V\nndq/w1Xju3Y8z0HweRDxvHFxip9fBza+KuH/uRzzMRkDxnbWRGS4uCbNkbAiTild+6GtOeH7e0oU\nKv98b6b5cQ5fra/Czpfv2FZjqVWtXR8auIJMOm37HEUJgbM4aUklJ6qzUXOAEjIhhJA5pesqNK30\nRZPpVBI3vWclEgnrVXRNjbfVddBQQiaEEDKnGptabUvWE+OjSCQS86Ys7RXdqYsQQggJAErIhBBC\nSABQQiaEEEICgBIyIYQQEgCUkAkhhJAAoIRMCCGEBAAlZEIIISQAKCETQgghAUAJuQKMMfh9K3DG\nWFVuT6fI/h5qDkA84u/9oTnA9/v5AnDd2ckJq1v4VcrsAOSvatzr0P+Y1bjNI2Oowuvpf0wjnv/b\nWY15hDofVBfdqcsjs5sMAHAc8+Um7mY3mWhIQl7VkXPYV9iOKHCQRR7XtiYwlsyhdyAFvcJRFQ2J\nqI3JWNIUxZWRNM68OYB8hdtaF5PR3BCFKArQdaPbU6WDXxQ4RBQR4DgoPsUEAIEDZEmELAmYSOUd\n9Wq2o0g8ljTFoGlGL+tETEEkVFlXquK2eZW037OKadzHvPKm9CajOxHna0s/s+ORcb913ZeY1Rzz\nHOdf44bqxDReT44z3k9+9EAmM1FCdqnU5FbJpGcOdJ7nC29yQeAhCjqyeRWah1zHAQjJPERxstNP\nXU0I0ZCIgdEMBseyrmOKAoeGmhAUeTJmc30UH75BQXf/ON7oGfEQk8eylviUBMTzPOIRGfm8hnRO\ns/lraxyAaFicMmGaMVVVQyrrPiZgJGKdoahRBYd4RIam6RhPl74Pb8nt5IClTTHEI1JhW1WNYXA0\ng2Q6j7q4AlF0n0imJ0tB4MAYq2giNSf5yfe3PzE5zjqm1z7DZuKY3g+50phA9cd85THNHstTY1Zy\nomPdD9k8yfPnRIdMooTsULnG6YLAu56gilccgjDz+aLIQxAkaBpDKpuH01KhIvIQJd6ya5Qsi2ht\njKImKqNvMIlMzlm2r4/LiIQky4lCkUW8a2ktWuoj6OwaxJURZ8m+rTGKurhSso2hJAmQRB7prIq8\nw3ZNoTJ9f0VRQI3AI51Xkc87i8kDAAfLjlEMAC/wqI0pyORVZBwm+4a4gkX1YUglEm4mp+HSUArR\nsIRETHH0frKbzM33mPEc5njCLzXJF8fUdR267n9MTXMe0258Tsb0Nj5nc8x7iQlYn4iYeN7/mMXb\n6fVEh8xECdkBp2etbia9mSuO0jFFkUOUK1/GNsrTAkSxfMxYRMa1ini1jJ0sWcqNhkQkYnLJxFEc\nMx5TsO66FgwMp/H/3hyAWmJpn4hJaGmIlY15NTDCIckoOafVkp+0CbxRnnb02S7HISxLUMTyZWzB\nTMRlcjcDoEgiFPFqGbtEUFnksbQ5hrAilp0YdQaMp/JIZ1XUxhSES5SxyyWOKftz9f1mTralyq5T\nE4f9+8mM4Xx1Vz7RmjGdrO6c/rtG0nC2uvM25svFdD7mzZjlSuMzqwz2MZ2cPLndd/NEpxp9kt9p\nKCHb8Po5md2kZ7c6KBfTKGNryOa0Kas1q/K0E6LAo75Qxk5jaCw3+e/xHBoTChS5fOKYsp08j+aG\nKP4rrqCrbwxvXhgt2gcOy5trEAmLcHthEM/ziEety9jRkOhpMrArY/OccQGL6z7KHId4VIaq6Zgo\nKmNzABYviiIRk11/9qhqDAOjGYQsythOJ/npBIGHrjOoqg5hWs/kSmKWWomZiYPneVf7b7e681re\ntVvdVTLmJ2P6N+YB6/2cPAlzF9Pu5MnNid3UmMaJjhFXozJ2BSghWzAGlvHGtCorOWVOeuZk4nTF\nYUcUBQgCj7yqIZPToFxdEVcSU5FFtDXGkIjm0TuQREQREQ1bl6fdxFy1rA7NDVH86/wAFFlCXVyp\n+EKY4jI2z3NQ5MrfwoUydjYPVTM+263kOi0G49jXxhRkcnmEFRFNdRHbUroTZhk7FpEQC0swkqb3\nmDzPFV30pYPjeE+Jo1jxSsz4xgDnKXGUimkmDC+Jwzqm1fj0J6Yg8IWkX8lYmn6iY2xnZRfUTY9p\nfGOk8ov0eJ63PNEhzlBCtqCqGiTJn5fGPHvUdf9KOhzHQZZECHxliXh6zFhExuJGD6tCm5iJmIL3\nLG/AeMr9RU82gUuWbyuJKUki8po/V2IDRmKOhGS0NUZ8uyJVZ8B4Mo9YWPbt2JuTs1Ea9idmcck5\n2DEny9h+xwT8uQodmFrG9jumruu+XDFeHNM4yaOE7BYV/S3oFX6NxUo1vg9Zje8uVuPLi/Pm2xHz\n5UuWVXg9OY6r2neB/Y85X8an/+bLvs+X1zNoKCETQgghAUAla0IIIXMqlZyo6PGFghIyIYSQOSXr\nY5gYTk75XTzMYcNN7y/8XFOTmO3NmnWUkAkhhMypRN0i1IYbp/xOzA+htrZujrZobtBnyIQQQkgA\nUEImhBBCAoASMiGEEBIAlJAJIYSQAKCETAghhAQAJWRCCCEkACghW/DrvsPTos6LmPPlLpfEf9V4\n21fntqnVuL3r/HjnV2M75898t/BRQrYgikbHEj/ux1rcks3vmIB/Mc1YkshdbT3o171oGRoTYdRE\nJd+GKDftv37RdAaeM1ov+kEUODTXhxGPSL7FBICwLABg0PXSvbHdMLsTMTbZli+IMavxvp8v47Oa\nY948Rn7dw1/X9flz//qAoRuDWJjsGeqtL6zJqrm6Mai8d9WZ/Ht/Y5rt3ASBhyQBubyKTG6yhZ5b\njDGIAodISAbHcYiGJYyncrg0mJrRz9gNDpMtNZjF77zQdR3JtDolhsBV1vWqNibj2sU1iChGV6pY\nRMPwWBbZvPd9l0UOdTUhyEWdyCppdWf2v53eHtCqp6/7mFM7HZknD167Cln17w410hoAAA3ZSURB\nVPVnfFYj5uT4NFswBnnMF2+72XbW66rZz25U70SUkG0IglCykbmdyYbk3IwJqLjpuJtJrzgmx1nH\ndNtc3a4huSyJkESGdFaFquqOa4+MMfAch0hIhChO7dUbj8iIhSVcHk5haCwL1UXGM5Ou1V94TsyM\nIZVVLbdDY0Y8t72RI7KAxU0xNNVHpvxeEgU01UeQTOcwlsy52neeA+JRGfGIPOM4Te+57XQitZrk\ni2MW98r1IybP84VVnZuTPDORW72nzfGpqnqht7PTmKXGSaVj3jrm/BjzXhciZkzzhJ54Rwm5DKtG\n5qUmk1IrDivuJ73yZ8PmpOckptWKYzqO4xAJSVA1DemsVtg3u21UJAGKLJR8HsdxaK6Poj6uoHcg\nhfFU3jaJ2iXimf+686Scz2tlV+oMRvtAc062S8wiz2FRXQjXtCZsJ/FoWEYkJGFkPINUWkW5Ym5E\nEVCXCIO3ed0ne/qWn0jtJvlik31ttauJyZ+Y5vPLvZ/tEsf0mKLIFVZ3TmPaHaO5HvOlqgxW/B7z\nxuOC45huTwiIPUrIDpWb9OxWB6WUm/SKB5DTs+qpDcJnTlBWpapyREFAPCIgk1ORy89MIYwxiDyH\nSHjmCq4USRKxvLUG48ksLg2lLZOjl1J0udWyVXm6HDMRlypjJ2IyVrTWIBKWHMXjOA51NWHEwipG\nk3mks+qM50gih7p4CIrsfIjare7cJI7pMYHSqzsv76dyK0aniaPY5OrO+m+tPj4qH3Nux7z7mP6N\n+XIxKRFXByVkl6ZPegAcrQ7KxQQmBw7HcY5WB/Yxp05QPF95zJAsQpEmy9gMAM9xCCsiJMn5pFQs\nHlUQi8i4NJTC8LhRxnazKi5lRmJmxnbnK/hgeHoZOywLaFsURUtD1FM8SRLRWCtiIpXFeDIP9epF\nZbGIhJqo4uk4Wa3uJlek3o4RMLM0bl4AVMmEPH3FyBireJKvTsz5N+b9jmkm4OJ5xMt1C8QeJWQP\nJic9HZVcADKdOemV+izKa8ziz3gqVVzGVlVmW552E7OlIYr6GgX/6R1HXvXnqlzASMb5vIp0zqcr\nfWGUsZvrw1jRZl+edioWURANyxibyCIeVXyJObm60ytKHNYxNfA878vXZYpXjDzP+7Lvxas78//9\nivlOHPPAZGncz5hkJnplK+DXBDI1pjHp+aka3zMUBQGS6M+kbJIlEWIVBrubC6icaqwJ+XrszSvR\n/V91eLtKvhy/Y3Kc91Vc6Zjw/fX0ekW7nfky5o1j5HtYUoQSMiGEEBIAlJAJIYSQAKCETAghhAQA\nJWRCCCEkAOgqa0IIIXNKFnSkklem/C4c9v41vfmKY/51ESCEEEKIR1SyJoQQQgKAEjIhhBASAJSQ\nCSGEkACghEwIIYQEACVkQgghJAAoIRNCCCEBQAmZEEIICQBKyHPkueeew+rVq3HixAkAwNDQEHbv\n3o3Nmzdj69at+Nvf/lZ4rtfHgiCXy+Hw4cPYvHkzPvGJT+Chhx4CAHR1deHOO+/E5s2bsX37drz1\n1luFv3Hz2Llz52Z9n+ycPHkSn/rUp3D77bdj69at+N3vfgdgYRzfb37zm+jo6MDq1avx73//u/B7\nv45l0I6z1f7mcjns3bsXt956K26//Xbcc8896O7uLvzNfD7OpY6vafqcBczv/Q0kRmbdxYsX2Y4d\nO9iOHTvY8ePHGWOMHThwgD366KOMMcbOnj3LNm7cyFRVreixIPjWt77FDh8+XPh5YGCAMcbYrl27\n2G9/+1vGGGPHjh1jd9xxR+E5Xh8Lgvb2dvbGG28wxhi7cOECW7NmDUsmk+zrX//6vD++p0+fZv39\n/ayjo4N1dnYWfl+NYxmE42y1v9lslp08ebLwnJ///Ods586dhZ/n8zgudXwZs56zym130Pc3iCgh\nzzJd19ndd9/N/vnPf7KdO3cW3twf+MAHCsmKMcY+/elPs1OnTrl+bPv27YXH5loqlWJr165lExMT\nU34/ODjI1q1bxzRNK/xuw4YNrLu72/NjQXHzzTez06dPM8YY6+zsZBs3bmS5XG5BHd9bbrmlMGFX\n41gG7TgX7+90r732Guvo6Cj8vBCO8/T9LTVnMbYw9jdI6F7Ws+zo0aNYt24drr/++sLvRkZGoGka\nGhoaCr9bvHgx+vr6XD/W1taGvr6+2dmZMrq7u5FIJPD444/j1KlTCIfD2Lt3L2pqarBo0SLw/OQn\nJq2trejt7UUsFvP02NKlS2d130p55JFHcP/99yMSiWBsbAyPPvooksnkgjy+ANDX1+f7sZwPx9n0\ns5/9DJs2bQKwcMex1ZwFLNz9nUv0GfIseuutt/DCCy/gi1/84ozHOI6b8jMrusW418fmmqqq6O3t\nxapVq/Dcc8/h4MGD2LdvHzRNm7Gddtvt9bHZpmkaHnvsMfzwhz/Eiy++iKNHj+KrX/0qNE2b8dyF\ncHxLqcaxDOJ+P/744+jq6sKDDz5Y+N1CG8d2cxaw8PZ3rlFCnkWnT59Gb28vPvrRj6KjowNnzpzB\noUOH8Kc//Qk8z2NwcLDw3N7eXrS1taG2ttb1Y62trbO6X6W0tbVBEARs3boVAHDddddhyZIluHjx\nIgYGBqDreuG5/f39aGtrQ2trK65cueL6sSDo7OzElStXsG7dOgDAmjVr0NLSgtdffx2CICy44wvA\n8/Gaz8cZAH7yk5/g+PHjePLJJ6EoCgB4OpZBP86l5qxf//rXC3J/5xol5Fl011134eWXX8aJEyfw\n4osv4v3vfz8OHz6Mu+66C7feeit+9atfAQDOnj2Ly5cv46abbgIA14+1t7fPwd7NVFdXh/Xr1+Ol\nl14CAPT09ODixYuF8tfzzz8PADh27BhaWlqwdOlS1NfXe3osCMxEYl4R3NXVhZ6eHqxYsWJBHl8A\nno/XfD7OR48exR/+8AccPXoUsVhsymML7ThbzVnf+MY3cOeddwJYePs716j94hzatWsXPve5z+Ej\nH/kIBgcH8dBDD+HChQuQZRmHDh0qvHm9PhYEPT09OHjwIIaHhyEIAu6//35s2rQJ58+fx4EDBzA8\nPIx4PI4jR45g1apVAOD5sSD44x//iB/96EcQBAG6rmPPnj34+Mc/viCO76FDh3Dy5EkMDg6itrYW\n0WgUL7zwQlWOZRCOs9X+/vSnP8WHP/xhLFu2DNFoFIwxKIqCZ599FoD3YxmE41zq+BYrnrPm+/4G\nESVkQgghJACoZE0IIYQEACVkQgghJAAoIRNCCCEBQAmZEEIICQBKyIQQQkgAUEImhBBCAoASMiGE\nEBIAlJAJIYSQAKCETIhPOjo68Morr8z1Zvjis5/9bOHuU4SQ2UEJmZBZYNXxiRBCilFCJsQHX/nK\nV9DX14e9e/di7dq1eOSRR7B69Wr88pe/xMc+9rHCfXpXr16N8+fPF/7u4YcfxoEDBwo/nz17Fjt3\n7kR7eztuu+02/PnPfy77bzPG8NRTT2Hz5s1Yu3Yttm7dis7OTgDAwMAAHnjgAaxfvx6bNm3CE088\nUfi7kZERfOlLX0J7ezva29uxY8cOjIyM4Lvf/S5effVVfPvb38batWvxta99za+XiRBiQ5zrDSBk\nIXj44Yfxj3/8A4cPH8aGDRsAAE888QSOHTuGX/ziF4WuQNP7wBa7fPky7r33Xhw5cgS33HILXnvt\nNdx7771YuXIlVqxYUfLvnnnmGfzmN7/BY489hpUrV6KrqwuyLAMA9u3bh2XLluGll15Cf38/du/e\njfr6emzfvh1PPfUUGGN45ZVXIEkSOjs7oSgK9u/fjzNnzmDLli3YsWOHj68SIcQOrZAJ8dH0Xi1f\n+MIXUF9fX0iQdr1cfv/732PDhg3o6OgAx3F43/veh02bNuHYsWO2/+azzz6Lffv2YeXKlQCA5cuX\no7W1FZcuXcKrr76KAwcOQJZlLFu2DJ///OcLbQ0lScLIyAjOnz8PjuNw/fXXIxwOV7L7hJAK0AqZ\nkCpy03T94sWLOH78eKEvLGMMmqZh27Zttn/X19dn2Sv40qVLiMfjU3r2Ll68GJcuXQIA3HPPPchm\ns3jggQeQTqexdetWPPjggxAEwfE2E0L8QwmZEJ9YlaOn/y4cDiOTyRR+HhgYKPx/a2srbrvtNhw5\ncsTVv9vW1obu7m6sXr16yu+bm5sxPj6OiYmJQlK+cOECmpubAQCRSAT79+/H/v370dPTg927d2PF\nihW44447bEvrhJDqoJI1IT5pbGxEd3e37XPe+9734vnnn4eu6/j73/+OEydOFB7btm0bXn75Zfzl\nL3+BpmnI5XI4e/Yszp07ZxvzM5/5DH7wgx8UntfV1YW+vj40NzfjxhtvxHe+8x1ks1l0d3fj6aef\nLqy4//rXv+Ltt98GYwzRaBSSJBVWx072hRDiL0rIhPjkvvvuw5NPPon29nZ8//vft1xlHjx4EKdO\nncJNN92Ep59+Glu2bCk81tzcjB//+Md45pln8MEPfhAbN27E9773PeTzedt/d9euXdi2bRv27NmD\ndevW4ctf/jJGR0cBGBebDQ8PY+PGjbj77rvxyU9+Etu3bwdgJO7du3dj7dq12LZtGz70oQ8VkvWu\nXbtw4sQJ3HzzzVOuAieEVA/H7K4yIYQQQsisoBUyIYQQEgB0URch88CWLVvQ29tb+JkxBo7jsGfP\nHtx3331zuGWEEL9QyZoQQggJACpZE0IIIQFACZkQQggJAErIhBBCSABQQiaEEEICgBIyIYQQEgCU\nkAkhhJAA+P9wFI6Q+KDXGAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f54d73ea090>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import seaborn as sns\n",
    "sns.jointplot(x='true_cost', y=\"predicted_cost\", data=df, kind='hex');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2> Cloud deploy model and predict </h2>\n",
    "\n",
    "Now that we have a working model, we can turn the model loose and train on the full dataset. The model can then be deployed, which essentially puts it on the Cloud and attaches a REST API to it so that we can invoke the trained model from the windmills."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Deleting and deploying autoawesome v1 from /content/autoawesome/notebooks/ml_trained/model ... this will take a few minutes\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ERROR: (gcloud.beta.ml.versions.delete) NOT_FOUND: Field: name Error: The specified model version was not found.\n",
      "Deleting model [autoawesome]...\n",
      "done.\n",
      "Creating version (this might take a few minutes)......\n",
      "............................................................................................................................................................................................................................done.\n"
     ]
    }
   ],
   "source": [
    "%bash\n",
    "MODEL_NAME=\"windmill\"\n",
    "MODEL_VERSION=\"v3\"\n",
    "MODEL_LOCATION=\"/content/autoawesome/notebooks/ml_trained/model\"\n",
    "echo \"Deleting and deploying $MODEL_NAME $MODEL_VERSION from $MODEL_LOCATION ... this will take a few minutes\"\n",
    "gcloud beta ml versions delete ${MODEL_VERSION} --model ${MODEL_NAME}\n",
    "gcloud beta ml models delete ${MODEL_NAME}\n",
    "gcloud beta ml models create ${MODEL_NAME} --regions $REGION\n",
    "gcloud beta ml versions create ${MODEL_VERSION} --model ${MODEL_NAME} --staging-bucket gs://${BUCKET} --origin ${MODEL_LOCATION}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After the model is deployed, we will want to test it.  An easy way to test a deployed ML model is to write out a file with some hypothetical inputs and then use gcloud to invoke the REST API."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2> Invoking REST API </h2>\n",
    "\n",
    "Here is how the windmills invoke our model.  Note that invoking a deployed ML model is just a REST API call. The windmill owners don't know anything about what ML model we are running and this way, those details are all hidden away. The input variables may be scaled during preprocessing, but again the client doesn't know any of that.\n",
    "\n",
    "<img src=\"serving_arch.png\"/>\n",
    "\n",
    "This preserves maximum flexbility."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from googleapiclient import discovery\n",
    "from oauth2client.client import GoogleCredentials\n",
    "import json\n",
    "\n",
    "#import google.cloud.ml.features as features\n",
    "#from google.cloud.ml import session_bundle\n",
    "\n",
    "credentials = GoogleCredentials.get_application_default()\n",
    "api = discovery.build('ml', 'v1beta1', credentials=credentials,\n",
    "            discoveryServiceUrl='https://storage.googleapis.com/cloud-ml/discovery/ml_v1beta1_discovery.json')\n",
    "\n",
    "request_data = {'instances':\n",
    "  [\n",
    "     # redacted to protect privacy of our windmill owners\n",
    "  ]\n",
    "}\n",
    "\n",
    "parent = 'projects/%s/models/%s/versions/%s' % (PROJECT, 'windmills', 'v3')\n",
    "response = api.projects().predict(body=request_data, name=parent).execute()\n",
    "print \"response={0}\".format(response)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Copyright 2017 Google Inc. Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
